2000-02-29 06:24:41 +00:00
|
|
|
/* packet_win.c
|
|
|
|
* Routines for popping a window to display current packet
|
|
|
|
*
|
|
|
|
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
|
|
|
|
*
|
2002-02-18 01:08:44 +00:00
|
|
|
* $Id: packet_win.c,v 1.33 2002/02/18 01:08:44 guy Exp $
|
2000-02-29 06:24:41 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
On Windows, use the directory in which the binary resides as the
directory in which global data files are stored. If an installed binary
is being run, that's the correct directory for them; if a build-tree
binary is being run, the "manuf" file will be there, and you can put
other data files there as well, if necessary.
Do the same with plugins, except that, if there's no
"plugins\\{version}" subdirectory of that directory, fall back on the
default installation directory, so you at least have a place where you
can put plugins for use by build-tree binaries. (Should we, instead,
have the Windows build procedure create a subdirectory of the "plugins"
source directory, with the plugin version number as its name, and copy
the plugins there, so you'd use the build-tree plugin binaries?)
Move "test_for_directory()" out of "util.c" and into
"epan/filesystem.c", with the other file system access portability
wrappers and convenience routines. Fix "util.h" not to declare it - or
other routines moved to "epan/filesystem.c" a while ago.
svn path=/trunk/; revision=3858
2001-08-21 06:39:18 +00:00
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
2000-02-29 06:24:41 +00:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/epan.h>
|
2000-02-29 06:24:41 +00:00
|
|
|
#include "main.h"
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/timestamp.h>
|
|
|
|
#include <epan/packet.h>
|
2000-02-29 06:24:41 +00:00
|
|
|
#include "summary.h"
|
|
|
|
#include "file.h"
|
2002-01-11 07:40:32 +00:00
|
|
|
#include "prefs.h"
|
2000-02-29 06:24:41 +00:00
|
|
|
#include "menu.h"
|
|
|
|
#include "../menu.h"
|
|
|
|
#include "column.h"
|
|
|
|
#include "print.h"
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/resolv.h>
|
2000-02-29 06:24:41 +00:00
|
|
|
#include "packet_win.h"
|
|
|
|
#include "simple_dialog.h"
|
|
|
|
#include "proto_draw.h"
|
|
|
|
#include "keys.h"
|
|
|
|
#include "gtkglobals.h"
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/plugins.h>
|
|
|
|
#include <epan/epan_dissect.h>
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
/* Data structure holding information about a packet-detail window. */
|
|
|
|
struct PacketWinData {
|
2000-09-09 10:26:58 +00:00
|
|
|
frame_data *frame; /* The frame being displayed */
|
2000-05-19 23:07:04 +00:00
|
|
|
union wtap_pseudo_header pseudo_header; /* Pseudo-header for packet */
|
2000-02-29 06:24:41 +00:00
|
|
|
guint8 *pd; /* Data for packet */
|
|
|
|
GtkWidget *main;
|
|
|
|
GtkWidget *tv_scrollw;
|
|
|
|
GtkWidget *tree_view;
|
2001-03-23 14:44:04 +00:00
|
|
|
GtkWidget *bv_nb_ptr;
|
2000-09-08 09:50:08 +00:00
|
|
|
field_info *finfo_selected;
|
2000-10-06 10:11:40 +00:00
|
|
|
epan_dissect_t *edt;
|
2000-02-29 06:24:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* 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);
|
2000-03-01 06:50:18 +00:00
|
|
|
static void destroy_new_window(GtkObject *object, gpointer user_data);
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
void new_window_cb(GtkWidget *w){
|
|
|
|
|
|
|
|
#define NewWinTitleLen 1000
|
|
|
|
|
We already set the foreground and background color for every frame,
which means we're already doing a "do something to the last row in the
packet list" operation on every frame we add to the list, so adding a
call to "gtk_clist_set_row_data()" won't make matters worse.
In addition, we already set one column in a row on a "change time
format" operation, so finding the row for a frame by calling
"gtk_clist_find_row_from_data()" doesn't turn a constant-time operation
into a linear-time operation, it just cranks the proportionality
constant up - it was quadratic before, alas, and it's still quadratic.
Adding calls to "gtk_clist_find_row_from_data()" to the "Find Frame" and
"Go To Frame" code does add an extra linear operation there, but those
operations shouldn't be common - and "Go To Frame", going to the last
frame on an ~100,000-frame big capture file, was quick, at least on my
450 MHz Pentium II machine, so maybe it won't be too bad.
And "select_packet()" either has to search the frame table for the frame
with the specified row number, or has to call "gtk_clist_get_row_data()"
to do that - the first is linear in the position of the frame in the
frame table, and the latter is linear in its position in the CList, and
the latter is less than or equal to the former, so the only thing making
it worse would be a change in the proportionality constant.
So it probably won't hurt performance by much.
Furthermore, if we add the ability to sort the display on an arbitrary
column, or to delete frames from the display - both of which are in the
wish list - storing the row number of the frame in the "frame_data"
structure won't necessarily work, as the row number can change out from
under us.
Therefore, reinstate the old way of doing things, where we associate
with each row a pointer to the "frame_data" structure for the row, using
"gtk_clist_set_row_data()".
svn path=/trunk/; revision=1703
2000-03-08 06:48:01 +00:00
|
|
|
int row;
|
2000-02-29 06:24:41 +00:00
|
|
|
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 */
|
We already set the foreground and background color for every frame,
which means we're already doing a "do something to the last row in the
packet list" operation on every frame we add to the list, so adding a
call to "gtk_clist_set_row_data()" won't make matters worse.
In addition, we already set one column in a row on a "change time
format" operation, so finding the row for a frame by calling
"gtk_clist_find_row_from_data()" doesn't turn a constant-time operation
into a linear-time operation, it just cranks the proportionality
constant up - it was quadratic before, alas, and it's still quadratic.
Adding calls to "gtk_clist_find_row_from_data()" to the "Find Frame" and
"Go To Frame" code does add an extra linear operation there, but those
operations shouldn't be common - and "Go To Frame", going to the last
frame on an ~100,000-frame big capture file, was quick, at least on my
450 MHz Pentium II machine, so maybe it won't be too bad.
And "select_packet()" either has to search the frame table for the frame
with the specified row number, or has to call "gtk_clist_get_row_data()"
to do that - the first is linear in the position of the frame in the
frame table, and the latter is linear in its position in the CList, and
the latter is less than or equal to the former, so the only thing making
it worse would be a change in the proportionality constant.
So it probably won't hurt performance by much.
Furthermore, if we add the ability to sort the display on an arbitrary
column, or to delete frames from the display - both of which are in the
wish list - storing the row number of the frame in the "frame_data"
structure won't necessarily work, as the row number can change out from
under us.
Therefore, reinstate the old way of doing things, where we associate
with each row a pointer to the "frame_data" structure for the row, using
"gtk_clist_set_row_data()".
svn path=/trunk/; revision=1703
2000-03-08 06:48:01 +00:00
|
|
|
/* Find what row this packet is in. */
|
|
|
|
row = gtk_clist_find_row_from_data(GTK_CLIST(packet_list),
|
2000-06-27 04:36:03 +00:00
|
|
|
cfile.current_frame);
|
We already set the foreground and background color for every frame,
which means we're already doing a "do something to the last row in the
packet list" operation on every frame we add to the list, so adding a
call to "gtk_clist_set_row_data()" won't make matters worse.
In addition, we already set one column in a row on a "change time
format" operation, so finding the row for a frame by calling
"gtk_clist_find_row_from_data()" doesn't turn a constant-time operation
into a linear-time operation, it just cranks the proportionality
constant up - it was quadratic before, alas, and it's still quadratic.
Adding calls to "gtk_clist_find_row_from_data()" to the "Find Frame" and
"Go To Frame" code does add an extra linear operation there, but those
operations shouldn't be common - and "Go To Frame", going to the last
frame on an ~100,000-frame big capture file, was quick, at least on my
450 MHz Pentium II machine, so maybe it won't be too bad.
And "select_packet()" either has to search the frame table for the frame
with the specified row number, or has to call "gtk_clist_get_row_data()"
to do that - the first is linear in the position of the frame in the
frame table, and the latter is linear in its position in the CList, and
the latter is less than or equal to the former, so the only thing making
it worse would be a change in the proportionality constant.
So it probably won't hurt performance by much.
Furthermore, if we add the ability to sort the display on an arbitrary
column, or to delete frames from the display - both of which are in the
wish list - storing the row number of the frame in the "frame_data"
structure won't necessarily work, as the row number can change out from
under us.
Therefore, reinstate the old way of doing things, where we associate
with each row a pointer to the "frame_data" structure for the row, using
"gtk_clist_set_row_data()".
svn path=/trunk/; revision=1703
2000-03-08 06:48:01 +00:00
|
|
|
g_assert(row != -1);
|
2000-06-27 04:36:03 +00:00
|
|
|
for( i = 0; i < cfile.cinfo.num_cols; ++i){
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
if ( gtk_clist_get_text(GTK_CLIST( packet_list),
|
We already set the foreground and background color for every frame,
which means we're already doing a "do something to the last row in the
packet list" operation on every frame we add to the list, so adding a
call to "gtk_clist_set_row_data()" won't make matters worse.
In addition, we already set one column in a row on a "change time
format" operation, so finding the row for a frame by calling
"gtk_clist_find_row_from_data()" doesn't turn a constant-time operation
into a linear-time operation, it just cranks the proportionality
constant up - it was quadratic before, alas, and it's still quadratic.
Adding calls to "gtk_clist_find_row_from_data()" to the "Find Frame" and
"Go To Frame" code does add an extra linear operation there, but those
operations shouldn't be common - and "Go To Frame", going to the last
frame on an ~100,000-frame big capture file, was quick, at least on my
450 MHz Pentium II machine, so maybe it won't be too bad.
And "select_packet()" either has to search the frame table for the frame
with the specified row number, or has to call "gtk_clist_get_row_data()"
to do that - the first is linear in the position of the frame in the
frame table, and the latter is linear in its position in the CList, and
the latter is less than or equal to the former, so the only thing making
it worse would be a change in the proportionality constant.
So it probably won't hurt performance by much.
Furthermore, if we add the ability to sort the display on an arbitrary
column, or to delete frames from the display - both of which are in the
wish list - storing the row number of the frame in the "frame_data"
structure won't necessarily work, as the row number can change out from
under us.
Therefore, reinstate the old way of doing things, where we associate
with each row a pointer to the "frame_data" structure for the row, using
"gtk_clist_set_row_data()".
svn path=/trunk/; revision=1703
2000-03-08 06:48:01 +00:00
|
|
|
row, i, &TextPtr)){
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
if (( strlen( Title) + strlen( TextPtr))
|
|
|
|
< ( NewWinTitleLen - 1)){
|
|
|
|
|
|
|
|
strcat( Title, TextPtr);
|
|
|
|
strcat( Title, " ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
create_new_window ( Title, tv_size, bv_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2001-11-20 10:37:16 +00:00
|
|
|
create_new_window(char *Title, gint tv_size, gint bv_size)
|
|
|
|
{
|
2000-02-29 06:24:41 +00:00
|
|
|
GtkWidget *main_w, *main_vbox, *pane,
|
2001-03-23 14:44:04 +00:00
|
|
|
*tree_view, *tv_scrollw,
|
|
|
|
*bv_nb_ptr;
|
2000-02-29 06:24:41 +00:00
|
|
|
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 */
|
2000-03-02 07:05:57 +00:00
|
|
|
create_tree_view(tv_size, &prefs, pane, &tv_scrollw, &tree_view,
|
|
|
|
prefs.gui_scrollbar_on_right);
|
2000-02-29 06:24:41 +00:00
|
|
|
gtk_widget_show(tree_view);
|
|
|
|
|
|
|
|
/* Byte view */
|
2002-02-18 01:08:44 +00:00
|
|
|
bv_nb_ptr = create_byte_view(bv_size, pane, prefs.gui_scrollbar_on_right);
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
/* Allocate data structure to represent this window. */
|
|
|
|
DataPtr = (struct PacketWinData *) g_malloc(sizeof(struct PacketWinData));
|
|
|
|
|
2000-09-09 10:26:58 +00:00
|
|
|
DataPtr->frame = cfile.current_frame;
|
2000-06-27 04:36:03 +00:00
|
|
|
memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header, sizeof DataPtr->pseudo_header);
|
2000-09-09 10:26:58 +00:00
|
|
|
DataPtr->pd = g_malloc(DataPtr->frame->cap_len);
|
|
|
|
memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len);
|
2001-12-18 19:09:08 +00:00
|
|
|
DataPtr->edt = epan_dissect_new(TRUE, TRUE);
|
|
|
|
epan_dissect_run(DataPtr->edt, &DataPtr->pseudo_header, DataPtr->pd,
|
|
|
|
DataPtr->frame, &cfile.cinfo);
|
2000-02-29 06:24:41 +00:00
|
|
|
DataPtr->main = main_w;
|
|
|
|
DataPtr->tv_scrollw = tv_scrollw;
|
|
|
|
DataPtr->tree_view = tree_view;
|
2001-03-23 14:44:04 +00:00
|
|
|
DataPtr->bv_nb_ptr = bv_nb_ptr;
|
2000-02-29 06:24:41 +00:00
|
|
|
detail_windows = g_list_append(detail_windows, DataPtr);
|
|
|
|
|
|
|
|
/* load callback handlers */
|
|
|
|
gtk_signal_connect(GTK_OBJECT(tree_view), "tree-select-row",
|
|
|
|
GTK_SIGNAL_FUNC(new_tree_view_select_row_cb), DataPtr);
|
|
|
|
|
2000-03-01 06:50:18 +00:00
|
|
|
gtk_signal_connect(GTK_OBJECT(tree_view), "tree-unselect-row",
|
|
|
|
GTK_SIGNAL_FUNC(new_tree_view_unselect_row_cb), DataPtr);
|
|
|
|
|
|
|
|
gtk_signal_connect(GTK_OBJECT(main_w), "destroy",
|
|
|
|
GTK_SIGNAL_FUNC(destroy_new_window), DataPtr);
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
/* draw the protocol tree & print hex data */
|
2001-12-06 04:25:09 +00:00
|
|
|
add_byte_views(DataPtr->frame, DataPtr->edt->tree, tree_view,
|
2001-11-20 10:37:16 +00:00
|
|
|
DataPtr->bv_nb_ptr);
|
2001-12-06 04:25:09 +00:00
|
|
|
proto_tree_draw(DataPtr->edt->tree, tree_view);
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2000-09-08 09:50:08 +00:00
|
|
|
DataPtr->finfo_selected = NULL;
|
2000-02-29 06:24:41 +00:00
|
|
|
gtk_widget_show(main_w);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2000-03-01 06:50:18 +00:00
|
|
|
destroy_new_window(GtkObject *object, gpointer user_data)
|
2000-02-29 06:24:41 +00:00
|
|
|
{
|
2000-03-01 06:50:18 +00:00
|
|
|
struct PacketWinData *DataPtr = user_data;
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
detail_windows = g_list_remove(detail_windows, DataPtr);
|
2000-10-06 10:11:40 +00:00
|
|
|
epan_dissect_free(DataPtr->edt);
|
2000-02-29 06:24:41 +00:00
|
|
|
g_free(DataPtr->pd);
|
|
|
|
g_free(DataPtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* called when a tree row is selected in the popup packet window */
|
2002-02-18 01:08:44 +00:00
|
|
|
static void
|
|
|
|
new_tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
field_info *finfo;
|
|
|
|
int i;
|
2001-03-23 14:44:04 +00:00
|
|
|
GtkWidget *byte_view;
|
2002-02-18 01:08:44 +00:00
|
|
|
const guint8 *data;
|
|
|
|
guint len;
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
set_notebook_page(DataPtr->bv_nb_ptr, finfo->ds_tvb);
|
|
|
|
byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
|
2001-03-24 23:53:07 +00:00
|
|
|
if ( !byte_view) /* exit if no hex window to write in */
|
2001-03-23 14:44:04 +00:00
|
|
|
return;
|
2002-02-18 01:08:44 +00:00
|
|
|
|
|
|
|
data = get_byte_view_data_and_length(byte_view, &len);
|
|
|
|
if (data == NULL) {
|
2001-03-23 14:44:04 +00:00
|
|
|
data = DataPtr->pd;
|
|
|
|
len = DataPtr->frame->cap_len;
|
|
|
|
}
|
2000-02-29 06:24:41 +00:00
|
|
|
|
2001-03-23 14:44:04 +00:00
|
|
|
DataPtr->finfo_selected = finfo;
|
|
|
|
packet_hex_print(GTK_TEXT(byte_view), data,
|
|
|
|
DataPtr->frame, finfo, len);
|
2000-02-29 06:24:41 +00:00
|
|
|
}
|
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/* called when a tree row is unselected in the popup packet window */
|
2000-02-29 06:24:41 +00:00
|
|
|
static void
|
|
|
|
new_tree_view_unselect_row_cb(GtkCTree *ctree, GList *node, gint column,
|
2002-02-18 01:08:44 +00:00
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
GtkWidget* byte_view;
|
|
|
|
const guint8* data;
|
|
|
|
guint len;
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
|
|
|
|
|
2000-09-08 09:50:08 +00:00
|
|
|
DataPtr->finfo_selected = NULL;
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
|
2001-03-24 23:53:07 +00:00
|
|
|
if ( !byte_view) /* exit if no hex window to write in */
|
2001-03-23 14:44:04 +00:00
|
|
|
return;
|
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
data = get_byte_view_data_and_length(byte_view, &len);
|
|
|
|
g_assert(data != NULL);
|
2001-03-23 14:44:04 +00:00
|
|
|
packet_hex_reprint(GTK_TEXT(byte_view));
|
2000-02-29 06:24:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
}
|
2000-09-08 09:50:08 +00:00
|
|
|
|
|
|
|
static void
|
2000-09-08 10:59:21 +00:00
|
|
|
redraw_hex_dump_cb(gpointer data, gpointer user_data)
|
2000-09-08 09:50:08 +00:00
|
|
|
{
|
|
|
|
struct PacketWinData *DataPtr = (struct PacketWinData *)data;
|
|
|
|
|
2001-03-23 14:44:04 +00:00
|
|
|
redraw_hex_dump(DataPtr->bv_nb_ptr, DataPtr->frame, DataPtr->finfo_selected);
|
2000-09-08 09:50:08 +00:00
|
|
|
}
|
|
|
|
|
2000-09-08 10:59:21 +00:00
|
|
|
/* Redraw the hex dump part of all the popup packet windows. */
|
2000-09-08 09:50:08 +00:00
|
|
|
void
|
2000-09-08 10:59:21 +00:00
|
|
|
redraw_hex_dump_packet_wins(void)
|
2000-09-08 09:50:08 +00:00
|
|
|
{
|
2000-09-08 10:59:21 +00:00
|
|
|
g_list_foreach(detail_windows, redraw_hex_dump_cb, NULL);
|
2000-09-08 09:50:08 +00:00
|
|
|
}
|