Jeff Foster's changes, with my additions, to allow the user to pop up a

window showing the protocol tree and hex/ASCII data for the currently
selected packet.

svn path=/trunk/; revision=1670
This commit is contained in:
Guy Harris 2000-02-29 06:24:41 +00:00
parent 25c6518e54
commit 7c11334000
14 changed files with 593 additions and 106 deletions

View File

@ -60,6 +60,7 @@ Guy Harris <guy@alum.mit.edu> {
NNTP support
ATM and LANE decoding
Q.931 decoding
Changes to the popup packet windows
Miscellaneous enhancements and fixes
}
@ -141,6 +142,7 @@ Jeff Foster <jfoste@woodward.com> {
NetBEUI/NBF support (NetBIOS atop 802.2 LLC, the
original NetBIOS encapsulation)
SMB Mailslot and Netlogin protocol support
Popup packet windows
}
Peter Torvals <petertv@xoommail.com> {

View File

@ -286,6 +286,17 @@ Collapses the protocol tree branches.
Expands all branches of the protocol tree.
=item Display:Expand All
Expands all branches of the protocol tree.
=item Display:Show Packet In New Window
Creates a new window containing a protocol tree view and a hex dump
window of the currently selected packet; this window will continue to
display that packet's protocol tree and data even if another packet is
selected.
=item Tools:Plugins
Allows you to use and configure dynamically loadable modules (see

7
file.c
View File

@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
* $Id: file.c,v 1.167 2000/02/21 08:18:00 guy Exp $
* $Id: file.c,v 1.168 2000/02/29 06:24:15 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -77,6 +77,7 @@
#include "util.h"
#include "simple_dialog.h"
#include "ui_util.h"
#include "prefs.h"
#include "gtk/proto_draw.h"
#include "dfilter.h"
#include "conversation.h"
@ -178,6 +179,10 @@ close_cap_file(capture_file *cf, void *w)
{
frame_data *fd, *fd_next;
/* Destroy all popup packet windows, as they refer to packets in the
capture file we're closing. */
destroy_packet_wins();
if (cf->fh) {
file_close(cf->fh);
cf->fh = NULL;

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for the GTK interface routines for Ethereal
#
# $Id: Makefile.am,v 1.24 2000/02/12 08:31:45 guy Exp $
# $Id: Makefile.am,v 1.25 2000/02/29 06:24:36 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@ -57,6 +57,8 @@ libui_a_SOURCES = \
main.h \
menu.c \
menu.h \
packet_win.c \
packet_win.h \
plugins_dlg.c \
prefs_dlg.c \
prefs_dlg.h \

View File

@ -23,7 +23,8 @@ OBJECTS=capture_dlg.obj \
gui_prefs.obj \
main.obj \
menu.obj \
plugins_dlg.obj \
packet_win.obj \
plugins_dlg.obj \
prefs_dlg.obj \
print_dlg.obj \
print_prefs.obj \

View File

@ -1,7 +1,7 @@
/* gtkglobals.h
* GTK-related Global defines, etc.
*
* $Id: gtkglobals.h,v 1.5 1999/12/30 23:02:54 gram Exp $
* $Id: gtkglobals.h,v 1.6 2000/02/29 06:24:36 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -36,10 +36,15 @@ extern GdkFont *m_r_font, *m_b_font;
extern GtkStyle *item_style;
void set_scrollbar_placement(int); /* 1=right, 0=left */
void set_scrollbar_placement_scrollw(GtkWidget *, int); /* 0=left, 1=right */
void set_scrollbar_placement_textw(GtkWidget *, GtkWidget *, int pos); /* 0=left, 1=right */
void set_scrollbar_placement_all(int); /* 1=right, 0=left */
void set_plist_sel_browse(gboolean);
void set_ptree_sel_browse(gboolean);
void set_ptree_line_style(gint style);
void set_ptree_expander_style(gint style);
void set_ptree_sel_browse(GtkWidget *, gboolean);
void set_ptree_sel_browse_all(gboolean);
void set_ptree_line_style(GtkWidget *, gint style);
void set_ptree_line_style_all(gint style);
void set_ptree_expander_style(GtkWidget *, gint style);
void set_ptree_expander_style_all(gint style);
#endif

View File

@ -1,7 +1,7 @@
/* gui_prefs.c
* Dialog box for GUI preferences
*
* $Id: gui_prefs.c,v 1.3 1999/12/30 23:02:55 gram Exp $
* $Id: gui_prefs.c,v 1.4 2000/02/29 06:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -241,7 +241,7 @@ scrollbar_menu_item_cb(GtkWidget *w, gpointer data)
gboolean value = GPOINTER_TO_INT(data);
temp_gui_scrollbar_on_right = value;
set_scrollbar_placement(value);
set_scrollbar_placement_all(value);
}
static void
@ -259,7 +259,7 @@ ptree_sel_browse_cb(GtkWidget *w, gpointer data)
gboolean value = GPOINTER_TO_INT(data);
temp_gui_ptree_sel_browse = value;
set_ptree_sel_browse(value);
set_ptree_sel_browse_all(value);
}
static void
@ -268,7 +268,7 @@ ptree_line_style_cb(GtkWidget *w, gpointer data)
gint value = GPOINTER_TO_INT(data);
temp_gui_ptree_line_style = value;
set_ptree_line_style(value);
set_ptree_line_style_all(value);
}
static void
@ -277,7 +277,7 @@ ptree_expander_style_cb(GtkWidget *w, gpointer data)
gint value = GPOINTER_TO_INT(data);
temp_gui_ptree_expander_style = value;
set_ptree_expander_style(value);
set_ptree_expander_style_all(value);
}
@ -302,19 +302,19 @@ gui_prefs_save(GtkWidget *w)
void
gui_prefs_cancel(GtkWidget *w)
{
/* Reset scrollbar placement value back to what the
* current preferences says it should be */
/* Reset GUI preference values back to what the
* current preferences says they should be */
temp_gui_scrollbar_on_right = prefs.gui_scrollbar_on_right;
temp_gui_plist_sel_browse = prefs.gui_plist_sel_browse;
temp_gui_ptree_sel_browse = prefs.gui_ptree_sel_browse;
temp_gui_ptree_line_style = prefs.gui_ptree_line_style;
temp_gui_ptree_expander_style = prefs.gui_ptree_expander_style;
set_scrollbar_placement(prefs.gui_scrollbar_on_right);
set_scrollbar_placement_all(prefs.gui_scrollbar_on_right);
set_plist_sel_browse(prefs.gui_plist_sel_browse);
set_ptree_sel_browse(prefs.gui_ptree_sel_browse);
set_ptree_line_style(prefs.gui_ptree_line_style);
set_ptree_expander_style(prefs.gui_ptree_expander_style);
set_ptree_sel_browse_all(prefs.gui_ptree_sel_browse);
set_ptree_line_style_all(prefs.gui_ptree_line_style);
set_ptree_expander_style_all(prefs.gui_ptree_expander_style);
gui_prefs_delete(w);
}

View File

@ -1,6 +1,6 @@
/* main.c
*
* $Id: main.c,v 1.106 2000/02/20 14:52:27 deniel Exp $
* $Id: main.c,v 1.107 2000/02/29 06:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -109,6 +109,7 @@
#include "proto_draw.h"
#include "dfilter.h"
#include "keys.h"
#include "packet_win.h"
#include "gtkglobals.h"
#include "plugins.h"
@ -138,6 +139,7 @@ static void follow_charset_toggle_cb(GtkWidget *w, gpointer parent_w);
static void follow_load_text(GtkWidget *text, char *filename, guint8 show_type);
static void follow_print_stream(GtkWidget *w, gpointer parent_w);
static char* hfinfo_numeric_format(header_field_info *hfinfo);
static void set_scrollbar_placement_main_window(int pos); /* 0=left, 1=right */
static void create_main_window(gint, gint, gint, e_prefs*);
/* About Ethereal window */
@ -853,19 +855,15 @@ static void
tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column, gpointer user_data)
{
field_info *finfo;
int tree_selected_start = -1;
int tree_selected_len = -1;
g_assert(node);
finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
if (!finfo) return;
finfo_selected = finfo;
tree_selected_start = finfo->start;
tree_selected_len = finfo->length;
packet_hex_print(GTK_TEXT(byte_view), cf.pd, cf.current_frame->cap_len,
tree_selected_start, tree_selected_len, cf.current_frame->encoding);
finfo->start, finfo->length, cf.current_frame->encoding);
}
static void
@ -896,27 +894,55 @@ void resolve_name_cb(GtkWidget *widget, gpointer data) {
}
}
/* Set the scrollbar placement of a scrolled window based upon pos value:
0 = left, 1 = right */
void
set_scrollbar_placement(int pos) /* 0=left, 1=right */
set_scrollbar_placement_scrollw(GtkWidget *scrollw, int pos) /* 0=left, 1=right */
{
if (pos) {
gtk_scrolled_window_set_placement( GTK_SCROLLED_WINDOW(pkt_scrollw),
GTK_CORNER_TOP_LEFT );
gtk_scrolled_window_set_placement( GTK_SCROLLED_WINDOW(tv_scrollw),
GTK_CORNER_TOP_LEFT );
gtk_widget_hide(bv_vscroll_left);
gtk_widget_show(bv_vscroll_right);
}
else {
gtk_scrolled_window_set_placement( GTK_SCROLLED_WINDOW(pkt_scrollw),
GTK_CORNER_TOP_RIGHT );
gtk_scrolled_window_set_placement( GTK_SCROLLED_WINDOW(tv_scrollw),
GTK_CORNER_TOP_RIGHT );
gtk_widget_hide(bv_vscroll_right);
gtk_widget_show(bv_vscroll_left);
gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(scrollw),
GTK_CORNER_TOP_LEFT);
} else {
gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(scrollw),
GTK_CORNER_TOP_RIGHT);
}
}
/* Set the scrollbar placement of a 3-box text window (hex display) based
upon pos value: 0 = left, 1 = right */
void
set_scrollbar_placement_textw(GtkWidget *vscroll_left, GtkWidget *vscroll_right,
int pos)
{
if (pos) {
gtk_widget_hide(vscroll_left);
gtk_widget_show(vscroll_right);
} else {
gtk_widget_hide(vscroll_right);
gtk_widget_show(vscroll_left);
}
}
/* Set the scrollbar placement of all the subwindows of the main window
based on pos value: 0 = left, 1 = right */
static void
set_scrollbar_placement_main_window(int pos)
{
set_scrollbar_placement_scrollw(pkt_scrollw, pos);
set_scrollbar_placement_scrollw(tv_scrollw, pos);
set_scrollbar_placement_textw(bv_vscroll_left, bv_vscroll_right, pos);
}
/* Set the scrollbar placement of all windows based on pos value:
0 = left, 1 = right */
void
set_scrollbar_placement_all(int pos)
{
set_scrollbar_placement_main_window(pos);
set_scrollbar_placement_packet_wins(pos);
}
/* Set the selection mode of the packet list window. */
void
set_plist_sel_browse(gboolean val)
{
@ -933,41 +959,66 @@ set_plist_sel_browse(gboolean val)
}
}
/* Set the selection mode of a given packet tree window. */
void
set_ptree_sel_browse(gboolean val)
set_ptree_sel_browse(GtkWidget *tv, gboolean val)
{
/* Yeah, GTK uses "browse" in the case where we do not, but oh well. I think
* "browse" in Ethereal makes more sense than "SINGLE" in GTK+ */
if (val) {
gtk_clist_set_selection_mode(GTK_CLIST(tree_view), GTK_SELECTION_SINGLE);
gtk_clist_set_selection_mode(GTK_CLIST(tv), GTK_SELECTION_SINGLE);
}
else {
gtk_clist_set_selection_mode(GTK_CLIST(tree_view), GTK_SELECTION_BROWSE);
gtk_clist_set_selection_mode(GTK_CLIST(tv), GTK_SELECTION_BROWSE);
}
}
/* Set the selection mode of all packet tree windows. */
void
set_ptree_line_style(gint style)
set_ptree_sel_browse_all(gboolean val)
{
set_ptree_sel_browse(tree_view, val);
set_ptree_sel_browse_packet_wins(val);
}
/* Set the line style of a given packet tree window. */
void
set_ptree_line_style(GtkWidget *tv, gint style)
{
/* I'm using an assert here since the preferences code limits
* the user input, both in the GUI and when reading the preferences file.
* If the value is incorrect, it's a program error, not a user-initiated error.
*/
g_assert(style >= GTK_CTREE_LINES_NONE && style <= GTK_CTREE_LINES_TABBED);
gtk_ctree_set_line_style( GTK_CTREE(tree_view), style );
gtk_ctree_set_line_style( GTK_CTREE(tv), style );
}
/* Set the line style of all packet tree window. */
void
set_ptree_expander_style(gint style)
set_ptree_line_style_all(gint style)
{
set_ptree_line_style(tree_view, style);
set_ptree_line_style_packet_wins(style);
}
/* Set the expander style of a given packet tree window. */
void
set_ptree_expander_style(GtkWidget *tv, gint style)
{
/* I'm using an assert here since the preferences code limits
* the user input, both in the GUI and when reading the preferences file.
* If the value is incorrect, it's a program error, not a user-initiated error.
*/
g_assert(style >= GTK_CTREE_EXPANDER_NONE && style <= GTK_CTREE_EXPANDER_CIRCULAR);
gtk_ctree_set_expander_style( GTK_CTREE(tree_view), style );
gtk_ctree_set_expander_style( GTK_CTREE(tv), style );
}
void
set_ptree_expander_style_all(gint style)
{
set_ptree_expander_style(tree_view, style);
set_ptree_expander_style_packet_wins(style);
}
void
file_quit_cmd_cb (GtkWidget *widget, gpointer data)
@ -1490,7 +1541,7 @@ static void
create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
{
GtkWidget *main_vbox, *menubar, *u_pane, *l_pane,
*bv_table, *stat_hbox,
*stat_hbox,
*filter_bt, *filter_cm, *filter_te,
*filter_reset;
GList *filter_list = NULL;
@ -1526,10 +1577,10 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
gtk_paned_gutter_size(GTK_PANED(u_pane), (GTK_PANED(u_pane))->handle_size);
l_pane = gtk_vpaned_new();
gtk_paned_gutter_size(GTK_PANED(l_pane), (GTK_PANED(l_pane))->handle_size);
gtk_container_add(GTK_CONTAINER(main_vbox), l_pane);
gtk_widget_show(u_pane);
gtk_paned_add1 (GTK_PANED(l_pane), u_pane);
gtk_container_add(GTK_CONTAINER(main_vbox), u_pane);
gtk_widget_show(l_pane);
gtk_paned_add2(GTK_PANED(u_pane), l_pane);
gtk_widget_show(u_pane);
/* Packet list */
pkt_scrollw = gtk_scrolled_window_new(NULL, NULL);
@ -1569,24 +1620,9 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
gtk_signal_connect_object(GTK_OBJECT(packet_list), "button_press_event",
GTK_SIGNAL_FUNC(popup_menu_handler), gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY));
gtk_widget_show(packet_list);
/* Tree view */
tv_scrollw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(tv_scrollw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_paned_add2(GTK_PANED(u_pane), tv_scrollw);
gtk_widget_set_usize(tv_scrollw, -1, tv_size);
gtk_widget_show(tv_scrollw);
tree_view = gtk_ctree_new(1, 0);
/* I need this next line to make the widget work correctly with hidden
* column titles and GTK_SELECTION_BROWSE */
gtk_clist_set_column_auto_resize( GTK_CLIST(tree_view), 0, TRUE );
gtk_container_add( GTK_CONTAINER(tv_scrollw), tree_view );
set_ptree_sel_browse(prefs->gui_ptree_sel_browse);
set_ptree_line_style(prefs->gui_ptree_line_style);
set_ptree_expander_style(prefs->gui_ptree_expander_style);
/* Tree view */
create_tree_view(tv_size, prefs, l_pane, &tv_scrollw, &tree_view);
gtk_signal_connect(GTK_OBJECT(tree_view), "tree-select-row",
GTK_SIGNAL_FUNC(tree_view_select_row_cb), NULL);
gtk_signal_connect(GTK_OBJECT(tree_view), "tree-unselect-row",
@ -1599,43 +1635,13 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
gdk_font_unref(item_style->font);
item_style->font = m_r_font;
/* Byte view. The table is only one row high, but 3 columns
* wide. The middle column contains the GtkText with the hex dump.
* The left and right columns contain vertical scrollbars. They both
* do the same thing, but only one will be shown at a time, in accordance
* with where the user wants the other vertical scrollbars places
* (on the left or the right).
*/
bv_table = gtk_table_new (1, 3, FALSE);
gtk_paned_pack2(GTK_PANED(l_pane), bv_table, FALSE, FALSE);
gtk_widget_set_usize(bv_table, -1, bv_size);
gtk_widget_show(bv_table);
/* Byte view. */
create_byte_view(bv_size, l_pane, &byte_view, &bv_vscroll_left,
&bv_vscroll_right);
byte_view = gtk_text_new(NULL, NULL);
gtk_text_set_editable(GTK_TEXT(byte_view), FALSE);
gtk_text_set_word_wrap(GTK_TEXT(byte_view), FALSE);
gtk_table_attach (GTK_TABLE (bv_table), byte_view, 1, 2, 0, 1,
GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
gtk_widget_show(byte_view);
/* The gtk_text widget doesn't scroll horizontally (see gtktext.c)
* in the GTK+ distribution, so I removed the horizontal scroll bar
* that used to be here. I tried the gtk_text widget with a
* gtk_scrolled_window w/ viewport, but the vertical scrollowing
* did not work well, and sometimes a few pixels were cut off on
* the bottom. */
bv_vscroll_left = gtk_vscrollbar_new(GTK_TEXT(byte_view)->vadj);
gtk_table_attach(GTK_TABLE(bv_table), bv_vscroll_left, 0, 1, 0, 1,
GTK_FILL, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
bv_vscroll_right = gtk_vscrollbar_new(GTK_TEXT(byte_view)->vadj);
gtk_table_attach(GTK_TABLE(bv_table), bv_vscroll_right, 2, 3, 0, 1,
GTK_FILL, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
/* Now that the 3 panes are created, set the vertical scrollbar
* on the left or right according to the user's preference */
set_scrollbar_placement(prefs->gui_scrollbar_on_right);
set_scrollbar_placement_main_window(prefs->gui_scrollbar_on_right);
/* Progress/filter/info box */
stat_hbox = gtk_hbox_new(FALSE, 1);

View File

@ -1,7 +1,7 @@
/* menu.c
* Menu routines
*
* $Id: menu.c,v 1.25 2000/02/20 14:52:28 deniel Exp $
* $Id: menu.c,v 1.26 2000/02/29 06:24:39 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -51,6 +51,7 @@
#include "summary_dlg.h"
#include "display_opts.h"
#include "prefs_dlg.h"
#include "packet_win.h"
#include "print.h"
#include "follow.h"
#include "keys.h"
@ -120,6 +121,7 @@ static GtkItemFactoryEntry menu_items[] =
{"/Display/_Go To Frame...", NULL, GTK_MENU_FUNC(goto_frame_cb), 0, NULL},
{"/Display/Collapse _All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL},
{"/Display/_Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL},
{"/Display/_Show Packet In New Window", NULL, GTK_MENU_FUNC(new_window_cb), 0, NULL},
{"/_Tools", NULL, NULL, 0, "<Branch>" },
#ifdef HAVE_PLUGINS
{"/Tools/_Plugins...", NULL, GTK_MENU_FUNC(tools_plugins_cmd_cb), 0, NULL},
@ -144,6 +146,7 @@ static GtkItemFactoryEntry packet_list_menu_items[] =
{"/Colorize Display...", NULL, GTK_MENU_FUNC(color_display_cb), 0, NULL},
{"/Print...", NULL, GTK_MENU_FUNC(file_print_cmd_cb), 0, NULL},
{"/Print Packet", NULL, GTK_MENU_FUNC(file_print_packet_cmd_cb), 0, NULL},
{"/Show Packet In New Window", NULL, GTK_MENU_FUNC(new_window_cb), 0, NULL},
};
static GtkItemFactoryEntry tree_view_menu_items[] =
@ -328,6 +331,7 @@ set_menus_for_selected_packet(gboolean have_selected_packet)
set_menu_sensitivity("/File/Print Packet", have_selected_packet);
set_menu_sensitivity("/Display/Collapse All", have_selected_packet);
set_menu_sensitivity("/Display/Expand All", have_selected_packet);
set_menu_sensitivity("/Display/Show Packet In New Window", have_selected_packet);
set_menu_sensitivity("/Tools/Follow TCP Stream",
have_selected_packet ? (pi.ipproto == 6) : FALSE);
set_menu_sensitivity("/Resolve Name",

339
gtk/packet_win.c Normal file
View File

@ -0,0 +1,339 @@
/* packet_win.c
* Routines for popping a window to display current packet
*
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
*
* $Id: packet_win.c,v 1.1 2000/02/29 06:24:40 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 1998 Gerald Combs
*
* Copied from main.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* To do:
* - Add close button to bottom.
* - improve the window Title and allow user to config it
* - Add print support ? ( could be a mess)
* - Add button to have main window jump to this packet ?
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "main.h"
#include "timestamp.h"
#include "packet.h"
#include "capture.h"
#include "summary.h"
#include "file.h"
#include "menu.h"
#include "../menu.h"
#include "prefs_dlg.h"
#include "column.h"
#include "print.h"
#include "resolv.h"
#include "follow.h"
#include "util.h"
#include "packet_win.h"
#include "simple_dialog.h"
#include "ui_util.h"
#include "proto_draw.h"
#include "dfilter.h"
#include "keys.h"
#include "gtkglobals.h"
#include "plugins.h"
/* Data structure holding information about a packet-detail window. */
struct PacketWinData {
gint cap_len;
gint encoding;
guint8 *pd; /* Data for packet */
proto_tree *protocol_tree; /* Protocol tree for packet */
GtkWidget *main;
GtkWidget *tv_scrollw;
GtkWidget *tree_view;
GtkWidget *byte_view;
GtkWidget *bv_vscroll_left;
GtkWidget *bv_vscroll_right;
};
/* List of all the packet-detail windows popped up. */
static GList *detail_windows;
static void new_tree_view_select_row_cb( GtkCTree *ctree, GList *node,
gint column, gpointer user_data);
static void new_tree_view_unselect_row_cb( GtkCTree *ctree, GList *node,
gint column, gpointer user_data);
static void create_new_window( char *Title, gint tv_size, gint bv_size);
static void destroy_new_window(gpointer data);
static void set_scrollbar_placement_packet_win(struct PacketWinData *DataPtr,
int pos);
void new_window_cb(GtkWidget *w){
#define NewWinTitleLen 1000
gint tv_size = 95, bv_size = 75;
int i;
char Title[ NewWinTitleLen] = "";
char *TextPtr;
/* build title of window by getting */
/* data from the packet_list GtkCList */
for( i = 0; i < cf.cinfo.num_cols; ++i){
if ( gtk_clist_get_text(GTK_CLIST( packet_list),
cf.current_frame->row, i, &TextPtr)){
if (( strlen( Title) + strlen( TextPtr))
< ( NewWinTitleLen - 1)){
strcat( Title, TextPtr);
strcat( Title, " ");
}
}
}
create_new_window ( Title, tv_size, bv_size);
}
static void
create_new_window ( char *Title, gint tv_size, gint bv_size){
GtkWidget *main_w, *main_vbox, *pane,
*tree_view, *byte_view, *tv_scrollw,
*bv_vscroll_left, *bv_vscroll_right;
struct PacketWinData *DataPtr;
main_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(main_w), Title);
gtk_window_set_default_size(GTK_WINDOW(main_w), DEF_WIDTH, -1);
/* Container for paned windows */
main_vbox = gtk_vbox_new(FALSE, 1);
gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
gtk_container_add(GTK_CONTAINER(main_w), main_vbox);
gtk_widget_show(main_vbox);
/* Panes for the tree and byte view */
pane = gtk_vpaned_new();
gtk_paned_gutter_size(GTK_PANED(pane), (GTK_PANED(pane))->handle_size);
gtk_container_add(GTK_CONTAINER(main_vbox), pane);
gtk_widget_show(pane);
/* Tree view */
create_tree_view(tv_size, &prefs, pane, &tv_scrollw, &tree_view);
gtk_widget_show(tree_view);
/* Byte view */
create_byte_view(bv_size, pane, &byte_view, &bv_vscroll_left,
&bv_vscroll_right);
/* Allocate data structure to represent this window. */
DataPtr = (struct PacketWinData *) g_malloc(sizeof(struct PacketWinData));
DataPtr->cap_len = cf.current_frame->cap_len;
DataPtr->encoding = cf.current_frame->encoding;
DataPtr->pd = g_malloc(DataPtr->cap_len);
memcpy(DataPtr->pd, cf.pd, DataPtr->cap_len);
DataPtr->protocol_tree = proto_tree_create_root();
dissect_packet(DataPtr->pd, cf.current_frame, DataPtr->protocol_tree);
DataPtr->main = main_w;
DataPtr->tv_scrollw = tv_scrollw;
DataPtr->tree_view = tree_view;
DataPtr->byte_view = byte_view;
DataPtr->bv_vscroll_left = bv_vscroll_left;
DataPtr->bv_vscroll_right = bv_vscroll_right;
detail_windows = g_list_append(detail_windows, DataPtr);
/* Now that the 2 panes are created, set the vertical scrollbar
* on the left or right according to the user's preference */
set_scrollbar_placement_packet_win(DataPtr, prefs.gui_scrollbar_on_right);
/* load callback handlers */
gtk_signal_connect(GTK_OBJECT(tree_view), "tree-select-row",
GTK_SIGNAL_FUNC(new_tree_view_select_row_cb), DataPtr);
/* This handler needs a destroy function */
/* to remove the stored packet data */
gtk_signal_connect_full(GTK_OBJECT(tree_view), "tree-unselect-row",
GTK_SIGNAL_FUNC(new_tree_view_unselect_row_cb), NULL, DataPtr,
&destroy_new_window, FALSE, FALSE);
/* draw the protocol tree & print hex data */
proto_tree_draw(DataPtr->protocol_tree, tree_view);
packet_hex_print( GTK_TEXT(byte_view), DataPtr->pd,
DataPtr->cap_len, -1, -1, DataPtr->encoding);
gtk_widget_show(main_w);
}
static void
destroy_new_window(gpointer data)
{
struct PacketWinData *DataPtr = data;
detail_windows = g_list_remove(detail_windows, DataPtr);
proto_tree_free(DataPtr->protocol_tree);
g_free(DataPtr->pd);
g_free(DataPtr);
}
static void
new_tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column,
gpointer user_data){
/* called when a tree row is selected in the popup packet window */
field_info *finfo;
struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
g_assert(node);
finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
if (!finfo) return;
finfo_selected = finfo;
packet_hex_print(GTK_TEXT(DataPtr->byte_view), DataPtr->pd,
DataPtr->cap_len, finfo->start, finfo->length,
DataPtr->encoding);
}
static void
new_tree_view_unselect_row_cb(GtkCTree *ctree, GList *node, gint column,
gpointer user_data){
/* called when a tree row is unselected in the popup packet window */
struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
packet_hex_print(GTK_TEXT(DataPtr->byte_view), DataPtr->pd,
DataPtr->cap_len, -1, -1, DataPtr->encoding);
}
/* Functions called from elsewhere to act on all popup packet windows. */
/* Destroy all popup packet windows. */
void
destroy_packet_wins(void)
{
struct PacketWinData *DataPtr;
/* Destroying a packet window causes it to be removed from
the list of packet windows, so we can't do a "g_list_foreach()"
to go through the list of all packet windows and destroy them
as we find them; instead, as long as the list is non-empty,
we destroy the first window on the list. */
while (detail_windows != NULL) {
DataPtr = (struct PacketWinData *)(detail_windows->data);
gtk_widget_destroy(DataPtr->main);
}
}
/* Set the scrollbar position of a given popup packet window based upon
pos value: 0 = left, 1 = right */
static void
set_scrollbar_placement_packet_win(struct PacketWinData *DataPtr, int pos)
{
set_scrollbar_placement_scrollw(DataPtr->tv_scrollw, pos);
set_scrollbar_placement_textw(DataPtr->bv_vscroll_left,
DataPtr->bv_vscroll_right, pos);
}
static void
set_scrollbar_placement_cb(gpointer data, gpointer user_data)
{
set_scrollbar_placement_packet_win((struct PacketWinData *)data,
*(int *)user_data);
}
/* Set the scrollbar position of all the popup packet windows based upon
pos value: 0 = left, 1 = right */
void
set_scrollbar_placement_packet_wins(int pos)
{
g_list_foreach(detail_windows, set_scrollbar_placement_cb, &pos);
}
static void
set_ptree_sel_browse_cb(gpointer data, gpointer user_data)
{
struct PacketWinData *DataPtr = (struct PacketWinData *)data;
set_ptree_sel_browse(DataPtr->tree_view, *(gboolean *)user_data);
}
/* Set the selection mode of all the popup packet windows. */
void
set_ptree_sel_browse_packet_wins(gboolean val)
{
g_list_foreach(detail_windows, set_ptree_sel_browse_cb, &val);
}
static void
set_ptree_line_style_cb(gpointer data, gpointer user_data)
{
struct PacketWinData *DataPtr = (struct PacketWinData *)data;
set_ptree_line_style(DataPtr->tree_view, *(gint *)user_data);
}
/* Set the selection mode of all the popup packet windows. */
void
set_ptree_line_style_packet_wins(gint style)
{
g_list_foreach(detail_windows, set_ptree_line_style_cb, &style);
}
static void
set_ptree_expander_style_cb(gpointer data, gpointer user_data)
{
struct PacketWinData *DataPtr = (struct PacketWinData *)data;
set_ptree_expander_style(DataPtr->tree_view, *(gint *)user_data);
}
/* Set the selection mode of all the popup packet windows. */
void
set_ptree_expander_style_packet_wins(gint style)
{
g_list_foreach(detail_windows, set_ptree_expander_style_cb, &style);
}

31
gtk/packet_win.h Normal file
View File

@ -0,0 +1,31 @@
/* packet_win.h
* Declarations for popping a window to display current packet
*
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
*
* $Id: packet_win.h,v 1.1 2000/02/29 06:24:40 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
extern void new_window_cb(GtkWidget *w);
void set_scrollbar_placement_packet_wins(int pos);
void set_ptree_sel_browse_packet_wins(gboolean val);
void set_ptree_line_style_packet_wins(gint style);
void set_ptree_expander_style_packet_wins(gint style);

View File

@ -1,7 +1,7 @@
/* gtkpacket.c
* Routines for GTK+ packet display
*
* $Id: proto_draw.c,v 1.13 2000/01/25 03:45:45 gerald Exp $
* $Id: proto_draw.c,v 1.14 2000/02/29 06:24:40 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -45,7 +45,9 @@
#include "packet.h"
#include "util.h"
#include "prefs.h"
#include "proto_draw.h"
#include "gtkglobals.h"
#define BYTE_VIEW_WIDTH 16
#define BYTE_VIEW_SEP 8
@ -55,6 +57,51 @@ extern GdkFont *m_r_font, *m_b_font;
static void
proto_tree_draw_node(GNode *node, gpointer data);
void
create_byte_view(gint bv_size, GtkWidget *pane, GtkWidget **byte_view_p,
GtkWidget **bv_vscroll_left_p, GtkWidget **bv_vscroll_right_p)
{
GtkWidget *bv_table, *byte_view, *bv_vscroll_left, *bv_vscroll_right;
/* Byte view. The table is only one row high, but 3 columns
* wide. The middle column contains the GtkText with the hex dump.
* The left and right columns contain vertical scrollbars. They both
* do the same thing, but only one will be shown at a time, in accordance
* with where the user wants the other vertical scrollbars places
* (on the left or the right).
*/
bv_table = gtk_table_new (1, 3, FALSE);
gtk_paned_pack2(GTK_PANED(pane), bv_table, FALSE, FALSE);
gtk_widget_set_usize(bv_table, -1, bv_size);
gtk_widget_show(bv_table);
byte_view = gtk_text_new(NULL, NULL);
gtk_text_set_editable(GTK_TEXT(byte_view), FALSE);
gtk_text_set_word_wrap(GTK_TEXT(byte_view), FALSE);
gtk_table_attach (GTK_TABLE (bv_table), byte_view, 1, 2, 0, 1,
GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
gtk_widget_show(byte_view);
/* The gtk_text widget doesn't scroll horizontally (see gtktext.c)
* in the GTK+ distribution, so I removed the horizontal scroll bar
* that used to be here. I tried the gtk_text widget with a
* gtk_scrolled_window w/ viewport, but the vertical scrolling
* did not work well, and sometimes a few pixels were cut off on
* the bottom. */
bv_vscroll_left = gtk_vscrollbar_new(GTK_TEXT(byte_view)->vadj);
gtk_table_attach(GTK_TABLE(bv_table), bv_vscroll_left, 0, 1, 0, 1,
GTK_FILL, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
bv_vscroll_right = gtk_vscrollbar_new(GTK_TEXT(byte_view)->vadj);
gtk_table_attach(GTK_TABLE(bv_table), bv_vscroll_right, 2, 3, 0, 1,
GTK_FILL, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
*byte_view_p = byte_view;
*bv_vscroll_left_p = bv_vscroll_left;
*bv_vscroll_right_p = bv_vscroll_right;
}
void
packet_hex_print(GtkText *bv, guint8 *pd, gint len, gint bstart, gint blen,
char_enc encoding) {
@ -161,6 +208,33 @@ packet_hex_print(GtkText *bv, guint8 *pd, gint len, gint bstart, gint blen,
}
}
void
create_tree_view(gint tv_size, e_prefs *prefs, GtkWidget *pane,
GtkWidget **tv_scrollw_p, GtkWidget **tree_view_p)
{
GtkWidget *tv_scrollw, *tree_view;
/* Tree view */
tv_scrollw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(tv_scrollw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_paned_pack1(GTK_PANED(pane), tv_scrollw, TRUE, TRUE);
gtk_widget_set_usize(tv_scrollw, -1, tv_size);
gtk_widget_show(tv_scrollw);
tree_view = gtk_ctree_new(1, 0);
/* I need this next line to make the widget work correctly with hidden
* column titles and GTK_SELECTION_BROWSE */
gtk_clist_set_column_auto_resize( GTK_CLIST(tree_view), 0, TRUE );
gtk_container_add( GTK_CONTAINER(tv_scrollw), tree_view );
set_ptree_sel_browse(tree_view, prefs->gui_ptree_sel_browse);
set_ptree_line_style(tree_view, prefs->gui_ptree_line_style);
set_ptree_expander_style(tree_view, prefs->gui_ptree_expander_style);
*tree_view_p = tree_view;
*tv_scrollw_p = tv_scrollw;
}
void expand_all_tree(proto_tree *protocol_tree, GtkWidget *tree_view) {
int i;
for(i=0; i < num_tree_types; i++) {

View File

@ -1,7 +1,7 @@
/* gtkpacket.h
* Definitions for GTK+ packet display structures and routines
*
* $Id: proto_draw.h,v 1.4 1999/11/22 06:24:56 gram Exp $
* $Id: proto_draw.h,v 1.5 2000/02/29 06:24:41 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -27,10 +27,14 @@
#ifndef __GTKPACKET_H__
#define __GTKPACKET_H__
void create_byte_view(gint bv_size, GtkWidget *pane, GtkWidget **byte_view_p,
GtkWidget **bv_vscroll_left_p, GtkWidget **bv_vscroll_right_p);
void packet_hex_print(GtkText *, guint8 *, gint, gint, gint, char_enc);
#define E_TREEINFO_FIELD_INFO_KEY "tree_info_finfo"
void create_tree_view(gint tv_size, e_prefs *prefs, GtkWidget *pane,
GtkWidget **tv_scrollw_p, GtkWidget **tree_view_p);
void proto_tree_draw(proto_tree *protocol_tree, GtkWidget *tree_view);
void expand_all_tree(proto_tree *protocol_tree, GtkWidget *tree_view);
void collapse_all_tree(proto_tree *protocol_tree, GtkWidget *tree_view);

View File

@ -1,7 +1,7 @@
/* ui_util.h
* Definitions for UI utility routines
*
* $Id: ui_util.h,v 1.3 2000/01/03 06:59:10 guy Exp $
* $Id: ui_util.h,v 1.4 2000/02/29 06:24:16 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -40,6 +40,9 @@ void set_main_window_name(gchar *);
pop up the existing one rather than creating a new one. */
void reactivate_window(GtkWidget *);
/* Destroy all popup packet windows. */
void destroy_packet_wins(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */