2 * Routines for popping a window to display current packet
4 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
6 * $Id: packet_win.c,v 1.11 2000/08/17 07:56:42 guy Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@zing.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 ?
50 #include "timestamp.h"
57 #include "prefs_dlg.h"
62 #include "packet_win.h"
63 #include "simple_dialog.h"
65 #include "proto_draw.h"
68 #include "gtkglobals.h"
71 /* Data structure holding information about a packet-detail window. */
72 struct PacketWinData {
75 union wtap_pseudo_header pseudo_header; /* Pseudo-header for packet */
76 guint8 *pd; /* Data for packet */
77 proto_tree *protocol_tree; /* Protocol tree for packet */
79 GtkWidget *tv_scrollw;
81 GtkWidget *bv_scrollw;
85 /* List of all the packet-detail windows popped up. */
86 static GList *detail_windows;
88 static void new_tree_view_select_row_cb( GtkCTree *ctree, GList *node,
89 gint column, gpointer user_data);
91 static void new_tree_view_unselect_row_cb( GtkCTree *ctree, GList *node,
92 gint column, gpointer user_data);
94 static void create_new_window( char *Title, gint tv_size, gint bv_size);
95 static void destroy_new_window(GtkObject *object, gpointer user_data);
97 void new_window_cb(GtkWidget *w){
99 #define NewWinTitleLen 1000
102 gint tv_size = 95, bv_size = 75;
104 char Title[ NewWinTitleLen] = "";
107 /* build title of window by getting */
108 /* data from the packet_list GtkCList */
109 /* Find what row this packet is in. */
110 row = gtk_clist_find_row_from_data(GTK_CLIST(packet_list),
111 cfile.current_frame);
113 for( i = 0; i < cfile.cinfo.num_cols; ++i){
115 if ( gtk_clist_get_text(GTK_CLIST( packet_list),
118 if (( strlen( Title) + strlen( TextPtr))
119 < ( NewWinTitleLen - 1)){
121 strcat( Title, TextPtr);
127 create_new_window ( Title, tv_size, bv_size);
132 create_new_window ( char *Title, gint tv_size, gint bv_size){
134 GtkWidget *main_w, *main_vbox, *pane,
135 *tree_view, *byte_view, *tv_scrollw,
137 struct PacketWinData *DataPtr;
139 main_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
141 gtk_window_set_title(GTK_WINDOW(main_w), Title);
142 gtk_window_set_default_size(GTK_WINDOW(main_w), DEF_WIDTH, -1);
144 /* Container for paned windows */
145 main_vbox = gtk_vbox_new(FALSE, 1);
146 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
147 gtk_container_add(GTK_CONTAINER(main_w), main_vbox);
148 gtk_widget_show(main_vbox);
150 /* Panes for the tree and byte view */
151 pane = gtk_vpaned_new();
152 gtk_paned_gutter_size(GTK_PANED(pane), (GTK_PANED(pane))->handle_size);
153 gtk_container_add(GTK_CONTAINER(main_vbox), pane);
154 gtk_widget_show(pane);
157 create_tree_view(tv_size, &prefs, pane, &tv_scrollw, &tree_view,
158 prefs.gui_scrollbar_on_right);
159 gtk_widget_show(tree_view);
162 create_byte_view(bv_size, pane, &byte_view, &bv_scrollw,
163 prefs.gui_scrollbar_on_right);
165 /* Allocate data structure to represent this window. */
166 DataPtr = (struct PacketWinData *) g_malloc(sizeof(struct PacketWinData));
168 DataPtr->cap_len = cfile.current_frame->cap_len;
169 DataPtr->encoding = cfile.current_frame->flags.encoding;
170 memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header, sizeof DataPtr->pseudo_header);
171 DataPtr->pd = g_malloc(DataPtr->cap_len);
172 memcpy(DataPtr->pd, cfile.pd, DataPtr->cap_len);
173 DataPtr->protocol_tree = proto_tree_create_root();
174 proto_tree_is_visible = TRUE;
175 dissect_packet(&DataPtr->pseudo_header, DataPtr->pd, cfile.current_frame,
176 DataPtr->protocol_tree);
177 proto_tree_is_visible = FALSE;
178 DataPtr->main = main_w;
179 DataPtr->tv_scrollw = tv_scrollw;
180 DataPtr->tree_view = tree_view;
181 DataPtr->byte_view = byte_view;
182 DataPtr->bv_scrollw = bv_scrollw;
183 detail_windows = g_list_append(detail_windows, DataPtr);
185 /* load callback handlers */
186 gtk_signal_connect(GTK_OBJECT(tree_view), "tree-select-row",
187 GTK_SIGNAL_FUNC(new_tree_view_select_row_cb), DataPtr);
189 gtk_signal_connect(GTK_OBJECT(tree_view), "tree-unselect-row",
190 GTK_SIGNAL_FUNC(new_tree_view_unselect_row_cb), DataPtr);
192 gtk_signal_connect(GTK_OBJECT(main_w), "destroy",
193 GTK_SIGNAL_FUNC(destroy_new_window), DataPtr);
195 /* draw the protocol tree & print hex data */
196 proto_tree_draw(DataPtr->protocol_tree, tree_view);
197 packet_hex_print( GTK_TEXT(byte_view), DataPtr->pd,
198 DataPtr->cap_len, -1, -1, DataPtr->encoding);
200 gtk_widget_show(main_w);
204 destroy_new_window(GtkObject *object, gpointer user_data)
206 struct PacketWinData *DataPtr = user_data;
208 detail_windows = g_list_remove(detail_windows, DataPtr);
209 proto_tree_free(DataPtr->protocol_tree);
215 new_tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column,
218 /* called when a tree row is selected in the popup packet window */
222 struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
225 finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
228 finfo_selected = finfo;
230 packet_hex_print(GTK_TEXT(DataPtr->byte_view), DataPtr->pd,
231 DataPtr->cap_len, finfo->start, finfo->length,
237 new_tree_view_unselect_row_cb(GtkCTree *ctree, GList *node, gint column,
240 /* called when a tree row is unselected in the popup packet window */
244 struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
246 packet_hex_print(GTK_TEXT(DataPtr->byte_view), DataPtr->pd,
247 DataPtr->cap_len, -1, -1, DataPtr->encoding);
250 /* Functions called from elsewhere to act on all popup packet windows. */
252 /* Destroy all popup packet windows. */
254 destroy_packet_wins(void)
256 struct PacketWinData *DataPtr;
258 /* Destroying a packet window causes it to be removed from
259 the list of packet windows, so we can't do a "g_list_foreach()"
260 to go through the list of all packet windows and destroy them
261 as we find them; instead, as long as the list is non-empty,
262 we destroy the first window on the list. */
263 while (detail_windows != NULL) {
264 DataPtr = (struct PacketWinData *)(detail_windows->data);
265 gtk_widget_destroy(DataPtr->main);
270 set_ptree_sel_browse_cb(gpointer data, gpointer user_data)
272 struct PacketWinData *DataPtr = (struct PacketWinData *)data;
274 set_ptree_sel_browse(DataPtr->tree_view, *(gboolean *)user_data);
277 /* Set the selection mode of all the popup packet windows. */
279 set_ptree_sel_browse_packet_wins(gboolean val)
281 g_list_foreach(detail_windows, set_ptree_sel_browse_cb, &val);
285 set_ptree_line_style_cb(gpointer data, gpointer user_data)
287 struct PacketWinData *DataPtr = (struct PacketWinData *)data;
289 set_ptree_line_style(DataPtr->tree_view, *(gint *)user_data);
292 /* Set the selection mode of all the popup packet windows. */
294 set_ptree_line_style_packet_wins(gint style)
296 g_list_foreach(detail_windows, set_ptree_line_style_cb, &style);
300 set_ptree_expander_style_cb(gpointer data, gpointer user_data)
302 struct PacketWinData *DataPtr = (struct PacketWinData *)data;
304 set_ptree_expander_style(DataPtr->tree_view, *(gint *)user_data);
307 /* Set the selection mode of all the popup packet windows. */
309 set_ptree_expander_style_packet_wins(gint style)
311 g_list_foreach(detail_windows, set_ptree_expander_style_cb, &style);