2000-09-08 09:50:08 +00:00
|
|
|
/* proto_draw.c
|
1999-03-23 03:14:46 +00:00
|
|
|
* Routines for GTK+ packet display
|
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
1999-03-23 03:14:46 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
Enable "Match Selected" only if there's a field selected *and* we can do
a "Match Selected" on it - we can't do a "Match Selected" if the field
has no value (e.g., FT_NULL) and has a length of 0.
If we unselect the current packet, we don't have a protocol tree, so we
don't have a currently selected field - clear the "Match Selected" menu
item and the display in the status line of information about the
currently selected field.
Move the low-level statusbar manipulation into "gtk/main.c", in routines
whose API doesn't expose anything GTK+-ish.
"close_cap_file()" calls one of those routines to clear out the status
bar, so it doesn't need to take a pointer to the statusbar widget as an
argument.
"clear_tree_and_hex_views()" is purely a display-manipulating routine;
move it to "gtk/proto_draw.c".
Extract from "tree_view_unselect_row_cb()" an "unselect_field()" routine
to do all the work that needs to be done if the currently selected
protocol tree row is unselected, and call it if the currently selected
packet list row is unselected (if it's unselected, there *is* no
protocol tree, so no row can be selected), as well as from
"tree_view_unselect_row_cb()".
Before pushing a new field-description message onto the statusbar, pop
the old one off.
Get rid of an unused variable (set, but not used).
svn path=/trunk/; revision=3513
2001-06-05 07:39:31 +00:00
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
1999-03-23 03:14:46 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2001-03-23 14:44:04 +00:00
|
|
|
* Jeff Foster, 2001/03/12, added support for displaying named
|
|
|
|
* data sources as tabbed hex windows
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1999-03-23 03:14:46 +00:00
|
|
|
* 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.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1999-03-23 03:14:46 +00:00
|
|
|
* 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.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1999-03-23 03:14:46 +00:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <ctype.h>
|
2003-11-30 23:05:45 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_IO_H
|
|
|
|
#include <io.h> /* open/close on win32 */
|
|
|
|
#endif
|
|
|
|
|
2004-02-20 17:31:00 +00:00
|
|
|
#ifdef HAVE_FCNTL_H
|
|
|
|
#include <fcntl.h>
|
|
|
|
#endif
|
|
|
|
|
2003-11-30 23:05:45 +00:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2003-11-30 18:01:20 +00:00
|
|
|
#include <unistd.h>
|
2003-11-30 23:05:45 +00:00
|
|
|
#endif
|
1999-03-23 03:14:46 +00:00
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
2001-07-09 22:54:15 +00:00
|
|
|
#include <gdk/gdkkeysyms.h>
|
1999-03-23 03:14:46 +00:00
|
|
|
|
2004-01-07 22:16:17 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2002-06-04 07:03:57 +00:00
|
|
|
#include <epan/epan_dissect.h>
|
|
|
|
|
2004-07-09 23:02:38 +00:00
|
|
|
#include "isprint.h"
|
|
|
|
|
1999-09-09 02:42:40 +00:00
|
|
|
#include "main.h"
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
2004-09-10 22:59:37 +00:00
|
|
|
#include <epan/charsets.h>
|
2001-03-02 23:10:12 +00:00
|
|
|
#include "menu.h"
|
|
|
|
#include "keys.h"
|
1999-03-23 03:14:46 +00:00
|
|
|
|
2004-09-27 22:55:15 +00:00
|
|
|
#include <epan/prefs.h>
|
2004-07-24 06:38:33 +00:00
|
|
|
#include "colors.h"
|
2003-11-29 06:09:54 +00:00
|
|
|
#include "file_dlg.h"
|
1999-09-09 02:42:40 +00:00
|
|
|
#include "proto_draw.h"
|
2000-09-08 09:50:08 +00:00
|
|
|
#include "packet_win.h"
|
2003-11-29 06:09:54 +00:00
|
|
|
#include "dlg_utils.h"
|
2002-01-11 06:43:18 +00:00
|
|
|
#include "ui_util.h"
|
2000-02-29 06:24:41 +00:00
|
|
|
#include "gtkglobals.h"
|
2002-11-11 15:39:06 +00:00
|
|
|
#include "compat_macros.h"
|
2004-02-11 01:23:25 +00:00
|
|
|
#include "alert_box.h"
|
2004-01-07 20:14:17 +00:00
|
|
|
#include "simple_dialog.h"
|
2004-04-23 19:43:06 +00:00
|
|
|
#include "progress_dlg.h"
|
2004-06-17 16:35:26 +00:00
|
|
|
#include "font_utils.h"
|
1999-03-23 03:14:46 +00:00
|
|
|
|
2004-02-20 17:31:00 +00:00
|
|
|
|
2004-06-30 06:58:59 +00:00
|
|
|
/* Win32 needs the O_BINARY flag for open() */
|
|
|
|
#ifndef O_BINARY
|
|
|
|
#define O_BINARY 0
|
|
|
|
#endif
|
|
|
|
|
1999-03-23 03:14:46 +00:00
|
|
|
#define BYTE_VIEW_WIDTH 16
|
1999-04-16 18:39:07 +00:00
|
|
|
#define BYTE_VIEW_SEP 8
|
1999-03-23 03:14:46 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
#define E_BYTE_VIEW_TREE_PTR "byte_view_tree_ptr"
|
|
|
|
#define E_BYTE_VIEW_TREE_VIEW_PTR "byte_view_tree_view_ptr"
|
2002-06-24 00:08:28 +00:00
|
|
|
#define E_BYTE_VIEW_NDIGITS_KEY "byte_view_ndigits"
|
2002-02-18 01:08:44 +00:00
|
|
|
#define E_BYTE_VIEW_TVBUFF_KEY "byte_view_tvbuff"
|
|
|
|
#define E_BYTE_VIEW_START_KEY "byte_view_start"
|
|
|
|
#define E_BYTE_VIEW_END_KEY "byte_view_end"
|
|
|
|
#define E_BYTE_VIEW_ENCODE_KEY "byte_view_encode"
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2004-06-17 16:35:26 +00:00
|
|
|
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
GtkStyle *item_style = NULL;
|
|
|
|
#endif
|
|
|
|
|
2003-11-03 21:00:05 +00:00
|
|
|
/* gtk_tree_view_expand_to_path doesn't exist in gtk+ v2.0 so we must include it
|
|
|
|
* when building with this version (taken from gtk+ v2.2.4) */
|
|
|
|
#if GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION == 0
|
|
|
|
/**
|
|
|
|
* gtk_tree_view_expand_to_path:
|
|
|
|
* @tree_view: A #GtkTreeView.
|
|
|
|
* @path: path to a row.
|
|
|
|
*
|
|
|
|
* Expands the row at @path. This will also expand all parent rows of
|
|
|
|
* @path as necessary.
|
|
|
|
*
|
|
|
|
* Since: 2.2
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
gtk_tree_view_expand_to_path (GtkTreeView *tree_view,
|
|
|
|
GtkTreePath *path)
|
|
|
|
{
|
|
|
|
gint i, depth;
|
|
|
|
gint *indices;
|
|
|
|
GtkTreePath *tmp;
|
|
|
|
|
|
|
|
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
|
|
|
|
g_return_if_fail (path != NULL);
|
|
|
|
|
|
|
|
depth = gtk_tree_path_get_depth (path);
|
|
|
|
indices = gtk_tree_path_get_indices (path);
|
|
|
|
|
|
|
|
tmp = gtk_tree_path_new ();
|
|
|
|
g_return_if_fail (tmp != NULL);
|
|
|
|
|
|
|
|
for (i = 0; i < depth; i++)
|
|
|
|
{
|
|
|
|
gtk_tree_path_append_index (tmp, indices[i]);
|
|
|
|
gtk_tree_view_expand_row (tree_view, tmp, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_tree_path_free (tmp);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
static GtkWidget *
|
|
|
|
add_byte_tab(GtkWidget *byte_nb, const char *name, tvbuff_t *tvb,
|
|
|
|
proto_tree *tree, GtkWidget *tree_view);
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
static void
|
2003-12-04 10:59:34 +00:00
|
|
|
proto_tree_draw_node(proto_node *node, gpointer data);
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/* Get the current text window for the notebook. */
|
|
|
|
GtkWidget *
|
|
|
|
get_notebook_bv_ptr(GtkWidget *nb_ptr)
|
|
|
|
{
|
|
|
|
int num;
|
2002-03-05 12:03:27 +00:00
|
|
|
GtkWidget *bv_page;
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
num = gtk_notebook_get_current_page(GTK_NOTEBOOK(nb_ptr));
|
|
|
|
bv_page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(nb_ptr), num);
|
2002-11-03 17:38:45 +00:00
|
|
|
if (bv_page)
|
|
|
|
return GTK_BIN(bv_page)->child;
|
|
|
|
else
|
|
|
|
return NULL;
|
2001-03-23 14:44:04 +00:00
|
|
|
}
|
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/*
|
|
|
|
* Get the data and length for a byte view, given the byte view page.
|
|
|
|
* Return the pointer, or NULL on error, and set "*data_len" to the length.
|
|
|
|
*/
|
|
|
|
const guint8 *
|
|
|
|
get_byte_view_data_and_length(GtkWidget *byte_view, guint *data_len)
|
|
|
|
{
|
|
|
|
tvbuff_t *byte_view_tvb;
|
|
|
|
const guint8 *data_ptr;
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-11-11 15:39:06 +00:00
|
|
|
byte_view_tvb = OBJECT_GET_DATA(byte_view, E_BYTE_VIEW_TVBUFF_KEY);
|
2002-02-18 01:08:44 +00:00
|
|
|
if (byte_view_tvb == NULL)
|
|
|
|
return NULL;
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
data_ptr = tvb_get_ptr(byte_view_tvb, 0, -1);
|
|
|
|
*data_len = tvb_length(byte_view_tvb);
|
|
|
|
return data_ptr;
|
2001-03-23 14:44:04 +00:00
|
|
|
}
|
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/*
|
|
|
|
* Set the current text window for the notebook to the window that
|
|
|
|
* refers to a particular tvbuff.
|
|
|
|
*/
|
2001-03-23 14:44:04 +00:00
|
|
|
void
|
2002-02-18 01:08:44 +00:00
|
|
|
set_notebook_page(GtkWidget *nb_ptr, tvbuff_t *tvb)
|
|
|
|
{
|
|
|
|
int num;
|
|
|
|
GtkWidget *bv_page, *bv;
|
|
|
|
tvbuff_t *bv_tvb;
|
|
|
|
|
|
|
|
for (num = 0;
|
|
|
|
(bv_page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(nb_ptr), num)) != NULL;
|
|
|
|
num++) {
|
|
|
|
bv = GTK_BIN(bv_page)->child;
|
2002-11-11 15:39:06 +00:00
|
|
|
bv_tvb = OBJECT_GET_DATA(bv, E_BYTE_VIEW_TVBUFF_KEY);
|
2002-02-18 01:08:44 +00:00
|
|
|
if (bv_tvb == tvb) {
|
|
|
|
/* Found it. */
|
|
|
|
gtk_notebook_set_page(GTK_NOTEBOOK(nb_ptr), num);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-03-23 14:44:04 +00:00
|
|
|
}
|
|
|
|
|
2000-09-08 10:59:21 +00:00
|
|
|
/* Redraw a given byte view window. */
|
2000-09-08 09:50:08 +00:00
|
|
|
void
|
2001-03-23 14:44:04 +00:00
|
|
|
redraw_hex_dump(GtkWidget *nb, frame_data *fd, field_info *finfo)
|
2000-09-08 09:50:08 +00:00
|
|
|
{
|
2002-02-18 01:08:44 +00:00
|
|
|
GtkWidget *bv;
|
|
|
|
const guint8 *data;
|
|
|
|
guint len;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2002-03-31 23:11:04 +00:00
|
|
|
bv = get_notebook_bv_ptr(nb);
|
2002-02-18 01:08:44 +00:00
|
|
|
if (bv != NULL) {
|
|
|
|
data = get_byte_view_data_and_length(bv, &len);
|
|
|
|
if (data != NULL)
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2002-02-18 01:08:44 +00:00
|
|
|
packet_hex_print(GTK_TEXT(bv), data, fd, finfo, len);
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
packet_hex_print(GTK_TEXT_VIEW(bv), data, fd, finfo, len);
|
|
|
|
#endif
|
2002-02-18 01:08:44 +00:00
|
|
|
}
|
2000-09-08 09:50:08 +00:00
|
|
|
}
|
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/* Redraw all byte view windows. */
|
2000-09-08 09:50:08 +00:00
|
|
|
void
|
2000-09-08 10:59:21 +00:00
|
|
|
redraw_hex_dump_all(void)
|
2000-09-08 09:50:08 +00:00
|
|
|
{
|
2004-05-18 00:05:12 +00:00
|
|
|
if (cfile.current_frame != NULL)
|
|
|
|
redraw_hex_dump( byte_nb_ptr, cfile.current_frame, cfile.finfo_selected);
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2000-09-08 10:59:21 +00:00
|
|
|
redraw_hex_dump_packet_wins();
|
2004-05-18 00:05:12 +00:00
|
|
|
|
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
/* XXX - this is a hack, to workaround a bug in GTK2.x!
|
|
|
|
when changing the font size, even refilling of the corresponding
|
|
|
|
gtk_text_buffer doesn't seem to trigger an update.
|
|
|
|
The only workaround is to freshly select the frame, which will remove any
|
|
|
|
existing notebook tabs and "restart" the whole byte view again. */
|
|
|
|
if (cfile.current_frame != NULL)
|
2005-02-04 18:44:44 +00:00
|
|
|
cf_goto_frame(&cfile, cfile.current_frame->num);
|
2004-05-18 00:05:12 +00:00
|
|
|
#endif
|
2000-09-08 09:50:08 +00:00
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2001-03-02 23:10:12 +00:00
|
|
|
static void
|
2002-03-05 11:56:00 +00:00
|
|
|
expand_tree(GtkCTree *ctree, GtkCTreeNode *node, gpointer user_data _U_)
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
static void
|
|
|
|
expand_tree(GtkTreeView *tree_view, GtkTreeIter *iter,
|
|
|
|
GtkTreePath *path _U_, gpointer user_data _U_)
|
|
|
|
#endif
|
2001-03-02 23:10:12 +00:00
|
|
|
{
|
2002-11-03 17:38:45 +00:00
|
|
|
field_info *finfo;
|
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
GtkTreeModel *model;
|
|
|
|
|
|
|
|
model = gtk_tree_view_get_model(tree_view);
|
|
|
|
gtk_tree_model_get(model, iter, 1, &finfo, -1);
|
|
|
|
#else
|
|
|
|
finfo = gtk_ctree_node_get_row_data( ctree, node);
|
|
|
|
#endif
|
|
|
|
g_assert(finfo);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Nodes with "finfo->tree_type" of -1 have no ett_ value, and
|
|
|
|
* are thus presumably leaf nodes and cannot be expanded.
|
|
|
|
*/
|
|
|
|
if (finfo->tree_type != -1) {
|
|
|
|
g_assert(finfo->tree_type >= 0 &&
|
|
|
|
finfo->tree_type < num_tree_types);
|
|
|
|
tree_is_expanded[finfo->tree_type] = TRUE;
|
|
|
|
}
|
2001-03-02 23:10:12 +00:00
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2001-03-02 23:10:12 +00:00
|
|
|
static void
|
2002-03-05 11:56:00 +00:00
|
|
|
collapse_tree(GtkCTree *ctree, GtkCTreeNode *node, gpointer user_data _U_)
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
static void
|
|
|
|
collapse_tree(GtkTreeView *tree_view, GtkTreeIter *iter,
|
|
|
|
GtkTreePath *path _U_, gpointer user_data _U_)
|
|
|
|
#endif
|
2001-03-02 23:10:12 +00:00
|
|
|
{
|
2002-11-03 17:38:45 +00:00
|
|
|
field_info *finfo;
|
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
GtkTreeModel *model;
|
|
|
|
|
|
|
|
model = gtk_tree_view_get_model(tree_view);
|
|
|
|
gtk_tree_model_get(model, iter, 1, &finfo, -1);
|
|
|
|
#else
|
|
|
|
finfo = gtk_ctree_node_get_row_data( ctree, node);
|
|
|
|
#endif
|
|
|
|
g_assert(finfo);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Nodes with "finfo->tree_type" of -1 have no ett_ value, and
|
|
|
|
* are thus presumably leaf nodes and cannot be collapsed.
|
|
|
|
*/
|
|
|
|
if (finfo->tree_type != -1) {
|
|
|
|
g_assert(finfo->tree_type >= 0 &&
|
|
|
|
finfo->tree_type < num_tree_types);
|
|
|
|
tree_is_expanded[finfo->tree_type] = FALSE;
|
|
|
|
}
|
2001-03-02 23:10:12 +00:00
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2001-07-09 22:54:15 +00:00
|
|
|
static void
|
2002-03-05 11:56:00 +00:00
|
|
|
toggle_tree(GtkCTree *ctree, GdkEventKey *event, gpointer user_data _U_)
|
2001-07-09 22:54:15 +00:00
|
|
|
{
|
|
|
|
if (event->keyval != GDK_Return)
|
|
|
|
return;
|
|
|
|
gtk_ctree_toggle_expansion(ctree, GTK_CTREE_NODE(ctree->clist.selection->data));
|
|
|
|
}
|
2002-11-03 17:38:45 +00:00
|
|
|
#endif
|
2001-07-09 22:54:15 +00:00
|
|
|
|
2002-06-24 00:08:28 +00:00
|
|
|
#define MAX_OFFSET_LEN 8 /* max length of hex offset of bytes */
|
|
|
|
#define BYTES_PER_LINE 16 /* max byte values in a line */
|
|
|
|
#define HEX_DUMP_LEN (BYTES_PER_LINE*3 + 1)
|
|
|
|
/* max number of characters hex dump takes -
|
|
|
|
2 digits plus trailing blank
|
|
|
|
plus separator between first and
|
|
|
|
second 8 digits */
|
|
|
|
#define DATA_DUMP_LEN (HEX_DUMP_LEN + 2 + BYTES_PER_LINE)
|
|
|
|
/* number of characters those bytes take;
|
|
|
|
3 characters per byte of hex dump,
|
|
|
|
2 blanks separating hex from ASCII,
|
|
|
|
1 character per byte of ASCII dump */
|
|
|
|
#define MAX_LINE_LEN (MAX_OFFSET_LEN + 2 + DATA_DUMP_LEN)
|
|
|
|
/* number of characters per line;
|
|
|
|
offset, 2 blanks separating offset
|
|
|
|
from data dump, data dump */
|
|
|
|
|
2001-03-02 23:10:12 +00:00
|
|
|
/* Which byte the offset is referring to. Associates
|
|
|
|
* whitespace with the preceding digits. */
|
|
|
|
static int
|
|
|
|
byte_num(int offset, int start_point)
|
|
|
|
{
|
|
|
|
return (offset - start_point) / 3;
|
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
struct field_lookup_info {
|
|
|
|
field_info *fi;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
};
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
lookup_finfo(GtkTreeModel *model, GtkTreePath *path _U_, GtkTreeIter *iter,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
field_info *fi;
|
|
|
|
struct field_lookup_info *fli = (struct field_lookup_info *)data;
|
|
|
|
|
|
|
|
gtk_tree_model_get(model, iter, 1, &fi, -1);
|
|
|
|
if (fi == fli->fi) {
|
|
|
|
fli->iter = *iter;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-03-20 06:34:09 +00:00
|
|
|
|
|
|
|
GtkTreePath *tree_find_by_field_info(GtkTreeView *tree_view, field_info *finfo) {
|
|
|
|
GtkTreeModel *model;
|
|
|
|
struct field_lookup_info fli;
|
|
|
|
|
|
|
|
model = gtk_tree_view_get_model(tree_view);
|
|
|
|
fli.fi = finfo;
|
|
|
|
gtk_tree_model_foreach(model, lookup_finfo, &fli);
|
|
|
|
|
|
|
|
return gtk_tree_model_get_path(model, &fli.iter);
|
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#endif
|
|
|
|
|
2001-03-02 23:10:12 +00:00
|
|
|
/* If the user selected a certain byte in the byte view, try to find
|
2004-01-27 20:36:48 +00:00
|
|
|
* the item in the GUI proto_tree that corresponds to that byte, and:
|
|
|
|
*
|
|
|
|
* if we succeed, select it, and return TRUE;
|
|
|
|
* if we fail, return FALSE. */
|
|
|
|
gboolean
|
2002-03-31 23:11:04 +00:00
|
|
|
byte_view_select(GtkWidget *widget, GdkEventButton *event)
|
2001-03-02 23:10:12 +00:00
|
|
|
{
|
2002-11-03 17:38:45 +00:00
|
|
|
proto_tree *tree;
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
GtkCTree *ctree;
|
|
|
|
GtkCTreeNode *node, *parent;
|
|
|
|
GtkText *bv = GTK_TEXT(widget);
|
|
|
|
#else
|
|
|
|
GtkTreeView *tree_view;
|
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreePath *first_path, *path;
|
|
|
|
GtkTreeIter parent;
|
|
|
|
GtkTextView *bv = GTK_TEXT_VIEW(widget);
|
|
|
|
gint x, y;
|
|
|
|
GtkTextIter iter;
|
|
|
|
struct field_lookup_info fli;
|
|
|
|
#endif
|
|
|
|
field_info *finfo;
|
|
|
|
int row, column;
|
|
|
|
int byte;
|
|
|
|
tvbuff_t *tvb;
|
|
|
|
guint ndigits;
|
|
|
|
int digits_start_1;
|
|
|
|
int digits_end_1;
|
|
|
|
int digits_start_2;
|
|
|
|
int digits_end_2;
|
|
|
|
int text_start_1;
|
|
|
|
int text_end_1;
|
|
|
|
int text_start_2;
|
|
|
|
int text_end_2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the number of digits of offset being displayed, and
|
|
|
|
* compute the columns of various parts of the display.
|
|
|
|
*/
|
2002-11-11 15:39:06 +00:00
|
|
|
ndigits = GPOINTER_TO_UINT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_NDIGITS_KEY));
|
2002-11-03 17:38:45 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The column of the first hex digit in the first half.
|
|
|
|
* That starts after "ndigits" digits of offset and two
|
|
|
|
* separating blanks.
|
|
|
|
*/
|
|
|
|
digits_start_1 = ndigits + 2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The column of the last hex digit in the first half.
|
|
|
|
* There are BYTES_PER_LINE/2 bytes displayed in the first
|
|
|
|
* half; there are 2 characters per byte, plus a separating
|
|
|
|
* blank after all but the last byte's characters.
|
|
|
|
*
|
|
|
|
* Then subtract 1 to get the last column of the first half
|
|
|
|
* rather than the first column after the first half.
|
|
|
|
*/
|
|
|
|
digits_end_1 = digits_start_1 + (BYTES_PER_LINE/2)*2 +
|
|
|
|
(BYTES_PER_LINE/2 - 1) - 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The column of the first hex digit in the second half.
|
|
|
|
* Add back the 1 to get the first column after the first
|
|
|
|
* half, and then add 2 for the 2 separating blanks between
|
|
|
|
* the halves.
|
|
|
|
*/
|
|
|
|
digits_start_2 = digits_end_1 + 3;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The column of the last hex digit in the second half.
|
|
|
|
* Add the same value we used to get "digits_end_1" from
|
|
|
|
* "digits_start_1".
|
|
|
|
*/
|
|
|
|
digits_end_2 = digits_start_2 + (BYTES_PER_LINE/2)*2 +
|
|
|
|
(BYTES_PER_LINE/2 - 1) - 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The column of the first "text dump" character in the first half.
|
|
|
|
* Add back the 1 to get the first column after the second
|
|
|
|
* half's hex dump, and then add 3 for the 3 separating blanks
|
|
|
|
* between the hex and text dummp.
|
|
|
|
*/
|
|
|
|
text_start_1 = digits_end_2 + 4;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The column of the last "text dump" character in the first half.
|
|
|
|
* There are BYTES_PER_LINE/2 bytes displayed in the first
|
|
|
|
* half; there is 1 character per byte.
|
|
|
|
*
|
|
|
|
* Then subtract 1 to get the last column of the first half
|
|
|
|
* rather than the first column after the first half.
|
|
|
|
*/
|
|
|
|
text_end_1 = text_start_1 + BYTES_PER_LINE/2 - 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The column of the first "text dump" character in the second half.
|
|
|
|
* Add back the 1 to get the first column after the first half,
|
|
|
|
* and then add 1 for the separating blank between the halves.
|
|
|
|
*/
|
|
|
|
text_start_2 = text_end_1 + 2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The column of the last "text dump" character in second half.
|
|
|
|
* Add the same value we used to get "text_end_1" from
|
|
|
|
* "text_start_1".
|
|
|
|
*/
|
|
|
|
text_end_2 = text_start_2 + BYTES_PER_LINE/2 - 1;
|
|
|
|
|
2002-11-11 15:39:06 +00:00
|
|
|
tree = OBJECT_GET_DATA(widget, E_BYTE_VIEW_TREE_PTR);
|
2002-11-03 17:38:45 +00:00
|
|
|
if (tree == NULL) {
|
|
|
|
/*
|
|
|
|
* Somebody clicked on the dummy byte view; do nothing.
|
|
|
|
*/
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2002-11-11 15:39:06 +00:00
|
|
|
ctree = GTK_CTREE(OBJECT_GET_DATA(widget, E_BYTE_VIEW_TREE_VIEW_PTR));
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
2002-11-11 15:39:06 +00:00
|
|
|
tree_view = GTK_TREE_VIEW(OBJECT_GET_DATA(widget,
|
|
|
|
E_BYTE_VIEW_TREE_VIEW_PTR));
|
2002-11-03 17:38:45 +00:00
|
|
|
#endif
|
2002-06-24 00:08:28 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
/* Given the mouse (x,y) and the current GtkText (h,v)
|
|
|
|
* adjustments, and the size of the font, figure out
|
|
|
|
* which text column/row the user selected. This could be off
|
|
|
|
* if the bold version of the font is bigger than the
|
|
|
|
* regular version of the font. */
|
2004-06-17 16:35:26 +00:00
|
|
|
column = (int) ((bv->hadj->value + event->x) / user_font_get_regular_width());
|
|
|
|
row = (int) ((bv->vadj->value + event->y) / user_font_get_regular_height());
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
/* get the row/column selected */
|
|
|
|
gtk_text_view_window_to_buffer_coords(bv,
|
|
|
|
gtk_text_view_get_window_type(bv, event->window),
|
2003-12-17 23:41:10 +00:00
|
|
|
(gint) event->x, (gint) event->y, &x, &y);
|
2002-11-03 17:38:45 +00:00
|
|
|
gtk_text_view_get_iter_at_location(bv, &iter, x, y);
|
|
|
|
row = gtk_text_iter_get_line(&iter);
|
|
|
|
column = gtk_text_iter_get_line_offset(&iter);
|
|
|
|
#endif
|
2002-06-24 00:08:28 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/* Given the column and row, determine which byte offset
|
|
|
|
* the user clicked on. */
|
|
|
|
if (column >= digits_start_1 && column <= digits_end_1) {
|
|
|
|
byte = byte_num(column, digits_start_1);
|
|
|
|
if (byte == -1) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (column >= digits_start_2 && column <= digits_end_2) {
|
|
|
|
byte = byte_num(column, digits_start_2);
|
|
|
|
if (byte == -1) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
byte += 8;
|
|
|
|
}
|
|
|
|
else if (column >= text_start_1 && column <= text_end_1) {
|
|
|
|
byte = column - text_start_1;
|
|
|
|
}
|
|
|
|
else if (column >= text_start_2 && column <= text_end_2) {
|
|
|
|
byte = 8 + column - text_start_2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* The user didn't select a hex digit or
|
|
|
|
* text-dump character. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
2002-06-24 00:08:28 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/* Add the number of bytes from the previous rows. */
|
|
|
|
byte += row * 16;
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/* Get the data source tvbuff */
|
2002-11-11 15:39:06 +00:00
|
|
|
tvb = OBJECT_GET_DATA(widget, E_BYTE_VIEW_TVBUFF_KEY);
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/* Find the finfo that corresponds to our byte. */
|
|
|
|
finfo = proto_find_field_from_offset(tree, byte, tvb);
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
if (!finfo) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
node = gtk_ctree_find_by_row_data(ctree, NULL, finfo);
|
|
|
|
g_assert(node);
|
|
|
|
|
|
|
|
/* Expand and select our field's row */
|
|
|
|
gtk_ctree_expand(ctree, node);
|
|
|
|
gtk_ctree_select(ctree, node);
|
|
|
|
expand_tree(ctree, node, NULL);
|
|
|
|
|
|
|
|
/* ... and its parents */
|
|
|
|
parent = GTK_CTREE_ROW(node)->parent;
|
|
|
|
while (parent) {
|
|
|
|
gtk_ctree_expand(ctree, parent);
|
|
|
|
expand_tree(ctree, parent, NULL);
|
|
|
|
parent = GTK_CTREE_ROW(parent)->parent;
|
|
|
|
}
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/* And position the window so the selection is visible.
|
|
|
|
* Position the selection in the middle of the viewable
|
|
|
|
* pane. */
|
|
|
|
gtk_ctree_node_moveto(ctree, node, 0, .5, 0);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
#else
|
|
|
|
model = gtk_tree_view_get_model(tree_view);
|
|
|
|
fli.fi = finfo;
|
|
|
|
gtk_tree_model_foreach(model, lookup_finfo, &fli);
|
|
|
|
|
|
|
|
/* Expand our field's row */
|
|
|
|
first_path = gtk_tree_model_get_path(model, &fli.iter);
|
|
|
|
gtk_tree_view_expand_row(tree_view, first_path, FALSE);
|
|
|
|
expand_tree(tree_view, &fli.iter, NULL, NULL);
|
|
|
|
|
|
|
|
/* ... and its parents */
|
|
|
|
while (gtk_tree_model_iter_parent(model, &parent, &fli.iter)) {
|
|
|
|
path = gtk_tree_model_get_path(model, &parent);
|
|
|
|
gtk_tree_view_expand_row(tree_view, path, FALSE);
|
|
|
|
expand_tree(tree_view, &parent, NULL, NULL);
|
|
|
|
fli.iter = parent;
|
|
|
|
gtk_tree_path_free(path);
|
|
|
|
}
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/* select our field's row */
|
|
|
|
gtk_tree_selection_select_path(gtk_tree_view_get_selection(tree_view),
|
|
|
|
first_path);
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/* And position the window so the selection is visible.
|
|
|
|
* Position the selection in the middle of the viewable
|
|
|
|
* pane. */
|
|
|
|
gtk_tree_view_scroll_to_cell(tree_view, first_path, NULL, TRUE, 0.5, 0.0);
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
gtk_tree_path_free(first_path);
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
return TRUE;
|
|
|
|
#endif
|
2001-03-02 23:10:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Calls functions for different mouse-button presses. */
|
|
|
|
static gint
|
|
|
|
byte_view_button_press_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
|
|
|
|
{
|
|
|
|
GdkEventButton *event_button = NULL;
|
|
|
|
|
|
|
|
if(widget == NULL || event == NULL || data == NULL) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2001-03-02 23:10:12 +00:00
|
|
|
if(event->type == GDK_BUTTON_PRESS) {
|
|
|
|
event_button = (GdkEventButton *) event;
|
|
|
|
|
2004-01-27 19:46:52 +00:00
|
|
|
/* To qoute the "Gdk Event Structures" doc:
|
|
|
|
* "Normally button 1 is the left mouse button, 2 is the middle button, and 3 is the right button" */
|
2001-03-02 23:10:12 +00:00
|
|
|
switch(event_button->button) {
|
|
|
|
|
|
|
|
case 1:
|
2002-03-31 23:11:04 +00:00
|
|
|
return byte_view_select(widget, event_button);
|
2001-03-02 23:10:12 +00:00
|
|
|
case 3:
|
|
|
|
return popup_menu_handler(widget, event, data);
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
GtkWidget *
|
2004-01-19 00:42:12 +00:00
|
|
|
byte_view_new(void)
|
2000-02-29 06:24:41 +00:00
|
|
|
{
|
2002-02-18 01:08:44 +00:00
|
|
|
GtkWidget *byte_nb;
|
2001-03-23 14:44:04 +00:00
|
|
|
|
|
|
|
byte_nb = gtk_notebook_new();
|
2002-02-18 01:08:44 +00:00
|
|
|
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(byte_nb), GTK_POS_BOTTOM);
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2004-02-06 19:19:12 +00:00
|
|
|
/* this will only have an effect, if no tabs are shown */
|
|
|
|
gtk_notebook_set_show_border(GTK_NOTEBOOK(byte_nb), FALSE);
|
|
|
|
|
2004-05-09 07:01:07 +00:00
|
|
|
/* set the tabs scrollable, if they don't fit into the pane */
|
|
|
|
gtk_notebook_set_scrollable(GTK_NOTEBOOK(byte_nb), TRUE);
|
|
|
|
|
|
|
|
/* enable a popup menu containing the tab labels, will be helpful if tabs don't fit into the pane */
|
|
|
|
gtk_notebook_popup_enable(GTK_NOTEBOOK(byte_nb));
|
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/* Add a placeholder byte view so that there's at least something
|
|
|
|
displayed in the byte view notebook. */
|
|
|
|
add_byte_tab(byte_nb, "", NULL, NULL, NULL);
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
return byte_nb;
|
|
|
|
}
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
static void
|
2002-03-05 11:56:00 +00:00
|
|
|
byte_view_realize_cb(GtkWidget *bv, gpointer data _U_)
|
2002-02-18 01:08:44 +00:00
|
|
|
{
|
2002-11-03 17:38:45 +00:00
|
|
|
const guint8 *byte_data;
|
|
|
|
guint byte_len;
|
|
|
|
|
|
|
|
byte_data = get_byte_view_data_and_length(bv, &byte_len);
|
|
|
|
if (byte_data == NULL) {
|
|
|
|
/* This must be the dummy byte view if no packet is selected. */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
packet_hex_print(GTK_TEXT(bv), byte_data, cfile.current_frame, NULL,
|
|
|
|
byte_len);
|
|
|
|
#else
|
|
|
|
packet_hex_print(GTK_TEXT_VIEW(bv), byte_data, cfile.current_frame, NULL,
|
|
|
|
byte_len);
|
|
|
|
#endif
|
2001-03-23 14:44:04 +00:00
|
|
|
}
|
|
|
|
|
2001-11-20 10:37:16 +00:00
|
|
|
static GtkWidget *
|
2002-02-18 01:08:44 +00:00
|
|
|
add_byte_tab(GtkWidget *byte_nb, const char *name, tvbuff_t *tvb,
|
2002-11-03 17:38:45 +00:00
|
|
|
proto_tree *tree, GtkWidget *tree_view)
|
2001-03-23 14:44:04 +00:00
|
|
|
{
|
|
|
|
GtkWidget *byte_view, *byte_scrollw, *label;
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
GtkTextBuffer *buf;
|
|
|
|
GtkStyle *style;
|
|
|
|
#endif
|
2001-03-23 14:44:04 +00:00
|
|
|
|
|
|
|
/* Byte view. Create a scrolled window for the text. */
|
2002-01-11 07:40:32 +00:00
|
|
|
byte_scrollw = scrolled_window_new(NULL, NULL);
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2001-03-02 23:10:12 +00:00
|
|
|
/* The horizontal scrollbar of the scroll-window doesn't seem
|
|
|
|
* to affect the GtkText widget at all, even when line wrapping
|
|
|
|
* is turned off in the GtkText widget and there is indeed more
|
|
|
|
* horizontal data. */
|
2000-03-02 07:05:57 +00:00
|
|
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(byte_scrollw),
|
2001-03-02 23:10:12 +00:00
|
|
|
/* Horizontal */GTK_POLICY_NEVER,
|
|
|
|
/* Vertical*/ GTK_POLICY_ALWAYS);
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
2004-02-06 19:19:12 +00:00
|
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(byte_scrollw),
|
|
|
|
GTK_SHADOW_IN);
|
2002-11-03 17:38:45 +00:00
|
|
|
#endif
|
2004-02-06 19:19:12 +00:00
|
|
|
/* Add scrolled pane to tabbed window */
|
|
|
|
label = gtk_label_new(name);
|
|
|
|
gtk_notebook_append_page(GTK_NOTEBOOK(byte_nb), byte_scrollw, label);
|
|
|
|
|
2000-03-02 07:05:57 +00:00
|
|
|
gtk_widget_show(byte_scrollw);
|
2000-02-29 06:24:41 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2000-02-29 06:24:41 +00:00
|
|
|
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);
|
2001-03-02 23:10:12 +00:00
|
|
|
gtk_text_set_line_wrap(GTK_TEXT(byte_view), FALSE);
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
byte_view = gtk_text_view_new();
|
|
|
|
gtk_text_view_set_editable(GTK_TEXT_VIEW(byte_view), FALSE);
|
|
|
|
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(byte_view), FALSE);
|
|
|
|
buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(byte_view));
|
|
|
|
style = gtk_widget_get_style(GTK_WIDGET(byte_view));
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_buffer_create_tag(buf, "plain", "font-desc", user_font_get_regular(), NULL);
|
2002-11-03 17:38:45 +00:00
|
|
|
gtk_text_buffer_create_tag(buf, "reverse",
|
2004-06-17 16:35:26 +00:00
|
|
|
"font-desc", user_font_get_regular(),
|
2002-11-03 17:38:45 +00:00
|
|
|
"foreground-gdk", &style->text[GTK_STATE_SELECTED],
|
|
|
|
"background-gdk", &style->base[GTK_STATE_SELECTED],
|
|
|
|
NULL);
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_buffer_create_tag(buf, "bold", "font-desc", user_font_get_bold(), NULL);
|
2002-11-03 17:38:45 +00:00
|
|
|
#endif
|
2002-11-11 15:39:06 +00:00
|
|
|
OBJECT_SET_DATA(byte_view, E_BYTE_VIEW_TVBUFF_KEY, tvb);
|
2000-03-02 07:05:57 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(byte_scrollw), byte_view);
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-11-11 15:39:06 +00:00
|
|
|
SIGNAL_CONNECT(byte_view, "show", byte_view_realize_cb, NULL);
|
|
|
|
SIGNAL_CONNECT(byte_view, "button_press_event", byte_view_button_press_cb,
|
|
|
|
OBJECT_GET_DATA(popup_menu_object, PM_HEXDUMP_KEY));
|
2001-03-02 23:10:12 +00:00
|
|
|
|
2002-11-11 15:39:06 +00:00
|
|
|
OBJECT_SET_DATA(byte_view, E_BYTE_VIEW_TREE_PTR, tree);
|
|
|
|
OBJECT_SET_DATA(byte_view, E_BYTE_VIEW_TREE_VIEW_PTR, tree_view);
|
2001-11-20 10:10:45 +00:00
|
|
|
|
2001-03-23 14:44:04 +00:00
|
|
|
gtk_widget_show(byte_view);
|
2000-02-29 06:24:41 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/* no tabs if this is the first page */
|
|
|
|
if (!(gtk_notebook_page_num(GTK_NOTEBOOK(byte_nb), byte_scrollw)))
|
|
|
|
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(byte_nb), FALSE);
|
2001-03-23 14:44:04 +00:00
|
|
|
else
|
2002-02-18 01:08:44 +00:00
|
|
|
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(byte_nb), TRUE);
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2004-04-23 19:43:06 +00:00
|
|
|
/* set this page (this will print the packet data) */
|
|
|
|
gtk_notebook_set_page(GTK_NOTEBOOK(byte_nb),
|
|
|
|
gtk_notebook_page_num(GTK_NOTEBOOK(byte_nb), byte_nb));
|
|
|
|
|
2001-03-23 14:44:04 +00:00
|
|
|
return byte_view;
|
|
|
|
}
|
|
|
|
|
2002-09-21 11:36:30 +00:00
|
|
|
void
|
|
|
|
add_main_byte_views(epan_dissect_t *edt)
|
|
|
|
{
|
|
|
|
add_byte_views(edt, tree_view, byte_nb_ptr);
|
|
|
|
}
|
|
|
|
|
2001-11-20 10:37:16 +00:00
|
|
|
void
|
2002-06-04 07:03:57 +00:00
|
|
|
add_byte_views(epan_dissect_t *edt, GtkWidget *tree_view,
|
2002-11-03 17:38:45 +00:00
|
|
|
GtkWidget *byte_nb_ptr)
|
2001-11-20 10:10:45 +00:00
|
|
|
{
|
2002-02-18 01:08:44 +00:00
|
|
|
GSList *src_le;
|
|
|
|
data_source *src;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get rid of all the old notebook tabs.
|
|
|
|
*/
|
|
|
|
while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr), 0) != NULL)
|
|
|
|
gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr), 0);
|
2001-11-20 10:37:16 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Add to the specified byte view notebook tabs for hex dumps
|
|
|
|
* of all the data sources for the specified frame.
|
|
|
|
*/
|
2002-06-04 07:03:57 +00:00
|
|
|
for (src_le = edt->pi.data_src; src_le != NULL; src_le = src_le->next) {
|
2002-02-18 01:08:44 +00:00
|
|
|
src = src_le->data;
|
2002-06-04 07:03:57 +00:00
|
|
|
add_byte_tab(byte_nb_ptr, src->name, src->tvb, edt->tree,
|
2002-11-03 17:38:45 +00:00
|
|
|
tree_view);
|
2001-11-20 10:37:16 +00:00
|
|
|
}
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2001-11-20 10:37:16 +00:00
|
|
|
/*
|
|
|
|
* Initially select the first byte view.
|
|
|
|
*/
|
2002-02-18 01:08:44 +00:00
|
|
|
gtk_notebook_set_page(GTK_NOTEBOOK(byte_nb_ptr), 0);
|
2000-02-29 06:24:41 +00:00
|
|
|
}
|
|
|
|
|
2004-05-31 12:06:28 +00:00
|
|
|
|
|
|
|
|
2003-11-29 06:09:54 +00:00
|
|
|
static GtkWidget *savehex_dlg=NULL;
|
|
|
|
|
|
|
|
static void
|
|
|
|
savehex_dlg_destroy_cb(void)
|
|
|
|
{
|
|
|
|
savehex_dlg = NULL;
|
|
|
|
}
|
|
|
|
|
2004-09-02 16:58:43 +00:00
|
|
|
extern void
|
|
|
|
copy_hex_cb(GtkWidget * w _U_, gpointer data _U_)
|
|
|
|
{
|
|
|
|
GtkWidget *bv;
|
|
|
|
int len;
|
|
|
|
int i=0;
|
|
|
|
const guint8 *data_p = NULL;
|
|
|
|
GString *ASCII_representation = g_string_new("");
|
|
|
|
GString *byte_str = g_string_new("");
|
|
|
|
|
|
|
|
bv = get_notebook_bv_ptr(byte_nb_ptr);
|
|
|
|
if (bv == NULL) {
|
|
|
|
/* shouldn't happen */
|
|
|
|
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not find the corresponding text window!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
data_p = get_byte_view_data_and_length(GTK_WIDGET(bv), &len);
|
|
|
|
|
2004-09-04 20:25:06 +00:00
|
|
|
g_string_sprintfa(byte_str,"%04x ",i); /* Offset 0000 */
|
2004-09-02 16:58:43 +00:00
|
|
|
for (i=0; i<len; i++){
|
2004-09-04 20:25:06 +00:00
|
|
|
g_string_sprintfa(ASCII_representation,"%c",isprint(*data_p) ? *data_p : '.');
|
|
|
|
g_string_sprintfa(byte_str," %02x",*data_p++);
|
2004-09-02 16:58:43 +00:00
|
|
|
if ((i+1)%16==0 && i!=0){
|
2004-09-04 20:25:06 +00:00
|
|
|
g_string_sprintfa(byte_str," %s\n%04x ",ASCII_representation->str,i+1);
|
2004-09-02 16:58:43 +00:00
|
|
|
g_string_assign (ASCII_representation,"");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ASCII_representation->len){
|
|
|
|
for (i=ASCII_representation->len; i<16; i++){
|
2004-09-04 20:25:06 +00:00
|
|
|
g_string_sprintfa(byte_str," ");
|
2004-09-02 16:58:43 +00:00
|
|
|
}
|
2004-09-04 20:25:06 +00:00
|
|
|
g_string_sprintfa(byte_str," %s\n",ASCII_representation->str);
|
2004-09-02 16:58:43 +00:00
|
|
|
}
|
|
|
|
/* Now that we have the byte data, copy it into the default clipboard */
|
|
|
|
copy_to_clipboard(byte_str);
|
|
|
|
g_string_free(byte_str, TRUE); /* Free the memory */
|
|
|
|
g_string_free(ASCII_representation, TRUE); /* Free the memory */
|
|
|
|
}
|
|
|
|
|
2004-05-31 12:06:28 +00:00
|
|
|
/* save the current highlighted hex data */
|
2003-11-29 06:09:54 +00:00
|
|
|
static void
|
|
|
|
savehex_save_clicked_cb(GtkWidget * w _U_, gpointer data _U_)
|
|
|
|
{
|
|
|
|
GtkWidget *bv;
|
|
|
|
int fd, start, end, len;
|
|
|
|
const guint8 *data_p = NULL;
|
2004-05-31 12:06:28 +00:00
|
|
|
const char *file = NULL;
|
2003-11-29 06:09:54 +00:00
|
|
|
|
2004-05-31 12:06:28 +00:00
|
|
|
#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
|
|
|
|
file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(savehex_dlg));
|
|
|
|
#else
|
|
|
|
file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(savehex_dlg));
|
|
|
|
#endif
|
2003-11-29 06:09:54 +00:00
|
|
|
|
|
|
|
if (!file ||! *file) {
|
2004-01-31 03:22:42 +00:00
|
|
|
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Please enter a filename!");
|
|
|
|
return;
|
2003-11-29 06:09:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Must check if file name exists first */
|
|
|
|
|
|
|
|
bv = get_notebook_bv_ptr(byte_nb_ptr);
|
|
|
|
if (bv == NULL) {
|
2004-01-31 03:22:42 +00:00
|
|
|
/* shouldn't happen */
|
|
|
|
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not find the corresponding text window!");
|
|
|
|
return;
|
2003-11-29 06:09:54 +00:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Retrieve the info we need
|
|
|
|
*/
|
|
|
|
end = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_START_KEY));
|
|
|
|
start = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_END_KEY));
|
|
|
|
data_p = get_byte_view_data_and_length(GTK_WIDGET(bv), &len);
|
|
|
|
|
|
|
|
if (data_p == NULL || start == -1 || start > end) {
|
2004-01-31 03:22:42 +00:00
|
|
|
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
|
|
|
|
"No data selected to save!");
|
2003-11-29 06:09:54 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-02-20 17:31:00 +00:00
|
|
|
fd = open(file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
|
2004-01-07 20:14:17 +00:00
|
|
|
if (fd == -1) {
|
2004-02-11 01:23:25 +00:00
|
|
|
open_failure_alert_box(file, errno, TRUE);
|
2004-01-31 03:22:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (write(fd, data_p + start, end - start) < 0) {
|
2004-02-11 01:37:13 +00:00
|
|
|
write_failure_alert_box(file, errno);
|
2004-01-31 03:22:42 +00:00
|
|
|
close(fd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (close(fd) < 0) {
|
2004-02-11 01:37:13 +00:00
|
|
|
write_failure_alert_box(file, errno);
|
2003-11-29 06:09:54 +00:00
|
|
|
return;
|
|
|
|
}
|
2003-12-18 20:36:45 +00:00
|
|
|
|
|
|
|
/* Get rid of the dialog box */
|
2004-05-26 03:49:24 +00:00
|
|
|
window_destroy(GTK_WIDGET(savehex_dlg));
|
2003-11-29 06:09:54 +00:00
|
|
|
}
|
|
|
|
|
2004-05-31 12:06:28 +00:00
|
|
|
/* Launch the dialog box to put up the file selection box etc */
|
|
|
|
void savehex_cb(GtkWidget * w _U_, gpointer data _U_)
|
|
|
|
{
|
|
|
|
int start, end, len;
|
|
|
|
const guint8 *data_p = NULL;
|
|
|
|
gchar *label;
|
|
|
|
|
|
|
|
GtkWidget *bv;
|
|
|
|
GtkWidget *dlg_lb;
|
|
|
|
|
|
|
|
|
|
|
|
/* don't show up the dialog, if no data has to be saved */
|
|
|
|
bv = get_notebook_bv_ptr(byte_nb_ptr);
|
|
|
|
if (bv == NULL) {
|
|
|
|
/* shouldn't happen */
|
|
|
|
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not find the corresponding text window!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
end = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_START_KEY));
|
|
|
|
start = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_END_KEY));
|
|
|
|
data_p = get_byte_view_data_and_length(GTK_WIDGET(bv), &len);
|
|
|
|
|
|
|
|
if (data_p == NULL || start == -1 || start > end) {
|
|
|
|
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No data selected to save!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if the window is already open, bring it to front */
|
|
|
|
if(savehex_dlg){
|
|
|
|
reactivate_window(savehex_dlg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build the dialog box we need.
|
|
|
|
*/
|
|
|
|
savehex_dlg = file_selection_new("Ethereal: Export Selected Packet Bytes", FILE_SELECTION_SAVE);
|
|
|
|
|
|
|
|
/* label */
|
|
|
|
label = g_strdup_printf("Will save %u %s of raw binary data to specified file.",
|
|
|
|
end - start, plurality(end - start, "byte", "bytes"));
|
|
|
|
dlg_lb = gtk_label_new(label);
|
|
|
|
g_free(label);
|
|
|
|
file_selection_set_extra_widget(savehex_dlg, dlg_lb);
|
|
|
|
gtk_widget_show(dlg_lb);
|
|
|
|
|
|
|
|
SIGNAL_CONNECT(savehex_dlg, "destroy", savehex_dlg_destroy_cb, NULL);
|
|
|
|
|
|
|
|
#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
|
|
|
|
if (gtk_dialog_run(GTK_DIALOG(savehex_dlg)) == GTK_RESPONSE_ACCEPT) {
|
|
|
|
savehex_save_clicked_cb(savehex_dlg, savehex_dlg);
|
|
|
|
} else {
|
|
|
|
window_destroy(savehex_dlg);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
/* Connect the ok_button to file_save_as_ok_cb function and pass along a
|
|
|
|
pointer to the file selection box widget */
|
|
|
|
SIGNAL_CONNECT(GTK_FILE_SELECTION (savehex_dlg)->ok_button, "clicked",
|
|
|
|
savehex_save_clicked_cb, savehex_dlg);
|
|
|
|
|
|
|
|
window_set_cancel_button(savehex_dlg,
|
|
|
|
GTK_FILE_SELECTION(savehex_dlg)->cancel_button, window_cancel_button_cb);
|
|
|
|
|
|
|
|
SIGNAL_CONNECT(savehex_dlg, "delete_event", window_delete_event_cb, NULL);
|
|
|
|
|
|
|
|
gtk_file_selection_set_filename(GTK_FILE_SELECTION(savehex_dlg), "");
|
|
|
|
|
|
|
|
gtk_widget_show_all(savehex_dlg);
|
|
|
|
window_present(savehex_dlg);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2004-04-23 19:43:06 +00:00
|
|
|
/* Update the progress bar this many times when reading a file. */
|
|
|
|
#define N_PROGBAR_UPDATES 100
|
|
|
|
|
2003-11-29 06:09:54 +00:00
|
|
|
|
2004-04-28 20:56:43 +00:00
|
|
|
/*
|
|
|
|
* XXX - at least in GTK+ 2.x, this is not fast - in one capture with a
|
|
|
|
* 64K-or-so reassembled HTTP reply, it takes about 3 seconds to construct
|
|
|
|
* the hex dump pane on a 1.4 GHz G4 PowerMac on OS X 10.3.3. (That's
|
|
|
|
* presumably why there's a progress bar for it.)
|
|
|
|
*
|
|
|
|
* Perhaps what's needed is a custom widget (either one that lets you stuff
|
|
|
|
* text into it more quickly, or one that's a "virtual" widget so that the
|
|
|
|
* text for a row is constructed, via a callback, when the row is to be
|
|
|
|
* displayed). A custom widget might also let us treat the offset, hex
|
|
|
|
* data, and ASCII data as three columns, so you can select purely in
|
|
|
|
* the hex dump column.
|
|
|
|
*/
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2002-02-18 01:08:44 +00:00
|
|
|
static void
|
|
|
|
packet_hex_print_common(GtkText *bv, const guint8 *pd, int len, int bstart,
|
|
|
|
int bend, int encoding)
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
static void
|
|
|
|
packet_hex_print_common(GtkTextView *bv, const guint8 *pd, int len, int bstart,
|
|
|
|
int bend, int encoding)
|
|
|
|
#endif
|
2000-09-09 10:26:58 +00:00
|
|
|
{
|
2002-11-03 17:38:45 +00:00
|
|
|
int i = 0, j, k, cur;
|
|
|
|
guchar line[MAX_LINE_LEN + 1];
|
|
|
|
static guchar hexchars[16] = {
|
|
|
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
|
|
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
|
|
|
guchar c = '\0';
|
|
|
|
unsigned int use_digits;
|
|
|
|
gboolean reverse, newreverse;
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
GdkFont *cur_font, *new_font;
|
|
|
|
GdkColor *fg, *bg;
|
|
|
|
#else
|
|
|
|
GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(bv));
|
|
|
|
GtkTextIter iter;
|
|
|
|
char *revstyle;
|
|
|
|
gchar *convline;
|
|
|
|
gsize newsize;
|
|
|
|
GtkTextMark *mark = NULL;
|
|
|
|
#endif
|
2000-09-08 09:50:08 +00:00
|
|
|
|
2004-04-23 19:43:06 +00:00
|
|
|
progdlg_t *progbar = NULL;
|
|
|
|
float progbar_val;
|
|
|
|
gboolean progbar_stop_flag;
|
|
|
|
GTimeVal progbar_start_time;
|
|
|
|
gchar progbar_status_str[100];
|
|
|
|
int progbar_nextstep;
|
|
|
|
int progbar_quantum;
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
1999-12-03 21:28:58 +00:00
|
|
|
/* Freeze the text for faster display */
|
|
|
|
gtk_text_freeze(bv);
|
|
|
|
|
|
|
|
/* Clear out the text */
|
|
|
|
gtk_text_set_point(bv, 0);
|
2002-08-28 21:04:11 +00:00
|
|
|
/* Keep GTK+ 1.2.3 through 1.2.6 from dumping core - see
|
2000-11-22 04:07:04 +00:00
|
|
|
http://www.ethereal.com/lists/ethereal-dev/199912/msg00312.html and
|
2000-01-25 03:45:45 +00:00
|
|
|
http://www.gnome.org/mailing-lists/archives/gtk-devel-list/1999-October/0051.shtml
|
|
|
|
for more information */
|
|
|
|
gtk_adjustment_set_value(bv->vadj, 0.0);
|
1999-12-03 21:28:58 +00:00
|
|
|
gtk_text_forward_delete(bv, gtk_text_get_length(bv));
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
gtk_text_buffer_set_text(buf, "", 0);
|
|
|
|
gtk_text_buffer_get_start_iter(buf, &iter);
|
|
|
|
#endif
|
1999-12-03 21:28:58 +00:00
|
|
|
|
2002-06-24 00:08:28 +00:00
|
|
|
/*
|
|
|
|
* How many of the leading digits of the offset will we supply?
|
|
|
|
* We always supply at least 4 digits, but if the maximum offset
|
|
|
|
* won't fit in 4 digits, we use as many digits as will be needed.
|
|
|
|
*/
|
|
|
|
if (((len - 1) & 0xF0000000) != 0)
|
|
|
|
use_digits = 8; /* need all 8 digits */
|
|
|
|
else if (((len - 1) & 0x0F000000) != 0)
|
|
|
|
use_digits = 7; /* need 7 digits */
|
|
|
|
else if (((len - 1) & 0x00F00000) != 0)
|
|
|
|
use_digits = 6; /* need 6 digits */
|
|
|
|
else if (((len - 1) & 0x000F0000) != 0)
|
|
|
|
use_digits = 5; /* need 5 digits */
|
|
|
|
else
|
|
|
|
use_digits = 4; /* we'll supply 4 digits */
|
|
|
|
|
|
|
|
/* Record the number of digits in this text view. */
|
2002-11-11 15:39:06 +00:00
|
|
|
OBJECT_SET_DATA(bv, E_BYTE_VIEW_NDIGITS_KEY, GUINT_TO_POINTER(use_digits));
|
2002-06-24 00:08:28 +00:00
|
|
|
|
2004-04-23 19:43:06 +00:00
|
|
|
/* Update the progress bar when it gets to this value. */
|
|
|
|
progbar_nextstep = 0;
|
|
|
|
/* When we reach the value that triggers a progress bar update,
|
|
|
|
bump that value by this amount. */
|
|
|
|
progbar_quantum = len/N_PROGBAR_UPDATES;
|
|
|
|
|
|
|
|
progbar_stop_flag = FALSE;
|
|
|
|
g_get_current_time(&progbar_start_time);
|
|
|
|
|
2001-03-23 14:44:04 +00:00
|
|
|
while (i < len) {
|
2004-04-23 19:43:06 +00:00
|
|
|
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
|
|
|
|
when we update it, we have to run the GTK+ main loop to get it
|
|
|
|
to repaint what's pending, and doing so may involve an "ioctl()"
|
|
|
|
to see if there's any pending input from an X server, and doing
|
|
|
|
that for every packet can be costly, especially on a big file. */
|
|
|
|
if (i >= progbar_nextstep) {
|
|
|
|
/* let's not divide by zero. I should never be started
|
|
|
|
* with count == 0, so let's assert that
|
|
|
|
*/
|
|
|
|
g_assert(len > 0);
|
|
|
|
progbar_val = (gfloat) i / len;
|
|
|
|
|
|
|
|
if (progbar == NULL)
|
|
|
|
/* Create the progress bar if necessary */
|
|
|
|
progbar = delayed_create_progress_dlg("Processing", "Packet Details",
|
|
|
|
&progbar_stop_flag,
|
|
|
|
&progbar_start_time,
|
|
|
|
progbar_val);
|
|
|
|
|
|
|
|
if (progbar != NULL) {
|
|
|
|
g_snprintf(progbar_status_str, sizeof(progbar_status_str),
|
|
|
|
"%4u of %u bytes", i, len);
|
|
|
|
update_progress_dlg(progbar, progbar_val, progbar_status_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
progbar_nextstep += progbar_quantum;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (progbar_stop_flag) {
|
|
|
|
/* Well, the user decided to abort the operation. Just stop,
|
|
|
|
and arrange to return TRUE to our caller, so they know it
|
|
|
|
was stopped explicitly. */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1999-03-23 03:14:46 +00:00
|
|
|
/* Print the line number */
|
2002-06-24 00:08:28 +00:00
|
|
|
j = use_digits;
|
|
|
|
cur = 0;
|
|
|
|
do {
|
|
|
|
j--;
|
|
|
|
c = (i >> (j*4)) & 0xF;
|
|
|
|
line[cur++] = hexchars[c];
|
|
|
|
} while (j != 0);
|
|
|
|
line[cur++] = ' ';
|
|
|
|
line[cur++] = ' ';
|
|
|
|
line[cur] = '\0';
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2000-09-08 09:50:08 +00:00
|
|
|
/* Display with inverse video ? */
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2000-09-08 10:59:21 +00:00
|
|
|
if (prefs.gui_hex_dump_highlight_style) {
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), &BLACK, &WHITE, line, -1);
|
2000-09-08 09:50:08 +00:00
|
|
|
/* Do we start in reverse? */
|
|
|
|
reverse = i >= bstart && i < bend;
|
|
|
|
fg = reverse ? &WHITE : &BLACK;
|
|
|
|
bg = reverse ? &BLACK : &WHITE;
|
|
|
|
j = i;
|
|
|
|
k = i + BYTE_VIEW_WIDTH;
|
|
|
|
cur = 0;
|
|
|
|
/* Print the hex bit */
|
|
|
|
while (i < k) {
|
2001-03-23 14:44:04 +00:00
|
|
|
if (i < len) {
|
2000-09-08 09:50:08 +00:00
|
|
|
line[cur++] = hexchars[(pd[i] & 0xf0) >> 4];
|
|
|
|
line[cur++] = hexchars[pd[i] & 0x0f];
|
|
|
|
} else {
|
|
|
|
line[cur++] = ' '; line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
newreverse = i >= bstart && i < bend;
|
|
|
|
/* Have we gone from reverse to plain? */
|
|
|
|
if (reverse && (reverse != newreverse)) {
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), fg, bg, line, cur);
|
2000-09-08 09:50:08 +00:00
|
|
|
fg = &BLACK;
|
|
|
|
bg = &WHITE;
|
|
|
|
cur = 0;
|
|
|
|
}
|
|
|
|
/* Inter byte space if not at end of line */
|
|
|
|
if (i < k) {
|
|
|
|
line[cur++] = ' ';
|
|
|
|
/* insert a space every BYTE_VIEW_SEP bytes */
|
|
|
|
if( ( i % BYTE_VIEW_SEP ) == 0 ) {
|
|
|
|
line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Have we gone from plain to reversed? */
|
|
|
|
if (!reverse && (reverse != newreverse)) {
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), fg, bg, line, cur);
|
2000-09-08 09:50:08 +00:00
|
|
|
fg = &WHITE;
|
|
|
|
bg = &BLACK;
|
|
|
|
cur = 0;
|
|
|
|
}
|
|
|
|
reverse = newreverse;
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
2000-09-08 09:50:08 +00:00
|
|
|
/* Print remaining part of line */
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), fg, bg, line, cur);
|
2000-09-08 09:50:08 +00:00
|
|
|
cur = 0;
|
|
|
|
/* Print some space at the end of the line */
|
|
|
|
line[cur++] = ' '; line[cur++] = ' '; line[cur++] = ' ';
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), &BLACK, &WHITE, line, cur);
|
2000-09-08 09:50:08 +00:00
|
|
|
cur = 0;
|
|
|
|
|
|
|
|
/* Print the ASCII bit */
|
|
|
|
i = j;
|
|
|
|
/* Do we start in reverse? */
|
|
|
|
reverse = i >= bstart && i < bend;
|
|
|
|
fg = reverse ? &WHITE : &BLACK;
|
|
|
|
bg = reverse ? &BLACK : &WHITE;
|
|
|
|
while (i < k) {
|
2001-03-23 14:44:04 +00:00
|
|
|
if (i < len) {
|
|
|
|
if (encoding == CHAR_ASCII) {
|
2000-09-08 09:50:08 +00:00
|
|
|
c = pd[i];
|
|
|
|
}
|
2001-03-23 14:44:04 +00:00
|
|
|
else if (encoding == CHAR_EBCDIC) {
|
2000-09-08 09:50:08 +00:00
|
|
|
c = EBCDIC_to_ASCII1(pd[i]);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
2001-04-10 12:07:40 +00:00
|
|
|
line[cur++] = isprint(c) ? c : '.';
|
2000-09-08 09:50:08 +00:00
|
|
|
} else {
|
|
|
|
line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
newreverse = i >= bstart && i < bend;
|
|
|
|
/* Have we gone from reverse to plain? */
|
|
|
|
if (reverse && (reverse != newreverse)) {
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), fg, bg, line, cur);
|
2000-09-08 09:50:08 +00:00
|
|
|
fg = &BLACK;
|
|
|
|
bg = &WHITE;
|
|
|
|
cur = 0;
|
|
|
|
}
|
|
|
|
if (i < k) {
|
|
|
|
/* insert a space every BYTE_VIEW_SEP bytes */
|
|
|
|
if( ( i % BYTE_VIEW_SEP ) == 0 ) {
|
|
|
|
line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Have we gone from plain to reversed? */
|
|
|
|
if (!reverse && (reverse != newreverse)) {
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), fg, bg, line, cur);
|
2000-09-08 09:50:08 +00:00
|
|
|
fg = &WHITE;
|
|
|
|
bg = &BLACK;
|
|
|
|
cur = 0;
|
|
|
|
}
|
|
|
|
reverse = newreverse;
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
2000-09-08 09:50:08 +00:00
|
|
|
/* Print remaining part of line */
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), fg, bg, line, cur);
|
2000-09-08 09:50:08 +00:00
|
|
|
cur = 0;
|
|
|
|
line[cur++] = '\n';
|
|
|
|
line[cur] = '\0';
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), &BLACK, &WHITE, line, -1);
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
2000-09-08 09:50:08 +00:00
|
|
|
else {
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_text_insert(bv, user_font_get_regular(), NULL, NULL, line, -1);
|
2000-09-08 09:50:08 +00:00
|
|
|
/* Do we start in bold? */
|
2004-06-17 16:35:26 +00:00
|
|
|
cur_font = (i >= bstart && i < bend) ? user_font_get_bold() : user_font_get_regular();
|
2000-09-08 09:50:08 +00:00
|
|
|
j = i;
|
|
|
|
k = i + BYTE_VIEW_WIDTH;
|
|
|
|
cur = 0;
|
|
|
|
/* Print the hex bit */
|
|
|
|
while (i < k) {
|
2001-03-23 14:44:04 +00:00
|
|
|
if (i < len) {
|
2000-09-08 09:50:08 +00:00
|
|
|
line[cur++] = hexchars[(pd[i] & 0xf0) >> 4];
|
|
|
|
line[cur++] = hexchars[pd[i] & 0x0f];
|
|
|
|
} else {
|
|
|
|
line[cur++] = ' '; line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
line[cur++] = ' ';
|
|
|
|
i++;
|
|
|
|
/* insert a space every BYTE_VIEW_SEP bytes */
|
|
|
|
if( ( i % BYTE_VIEW_SEP ) == 0 ) line[cur++] = ' ';
|
|
|
|
/* Did we cross a bold/plain boundary? */
|
2004-06-17 16:35:26 +00:00
|
|
|
new_font = (i >= bstart && i < bend) ? user_font_get_bold() : user_font_get_regular();
|
2000-09-08 09:50:08 +00:00
|
|
|
if (cur_font != new_font) {
|
|
|
|
gtk_text_insert(bv, cur_font, NULL, NULL, line, cur);
|
|
|
|
cur_font = new_font;
|
|
|
|
cur = 0;
|
|
|
|
}
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
2000-09-08 09:50:08 +00:00
|
|
|
line[cur++] = ' ';
|
|
|
|
gtk_text_insert(bv, cur_font, NULL, NULL, line, cur);
|
|
|
|
|
|
|
|
cur = 0;
|
|
|
|
i = j;
|
|
|
|
/* Print the ASCII bit */
|
2004-06-17 16:35:26 +00:00
|
|
|
cur_font = (i >= bstart && i < bend) ? user_font_get_bold() : user_font_get_regular();
|
2000-09-08 09:50:08 +00:00
|
|
|
while (i < k) {
|
2001-03-23 14:44:04 +00:00
|
|
|
if (i < len) {
|
|
|
|
if (encoding == CHAR_ASCII) {
|
2000-09-08 09:50:08 +00:00
|
|
|
c = pd[i];
|
|
|
|
}
|
2001-03-23 14:44:04 +00:00
|
|
|
else if (encoding == CHAR_EBCDIC) {
|
2000-09-08 09:50:08 +00:00
|
|
|
c = EBCDIC_to_ASCII1(pd[i]);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
2001-04-10 12:07:40 +00:00
|
|
|
line[cur++] = isprint(c) ? c : '.';
|
2000-09-08 09:50:08 +00:00
|
|
|
} else {
|
|
|
|
line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
/* insert a space every BYTE_VIEW_SEP bytes */
|
|
|
|
if( ( i % BYTE_VIEW_SEP ) == 0 ) line[cur++] = ' ';
|
|
|
|
/* Did we cross a bold/plain boundary? */
|
2004-06-17 16:35:26 +00:00
|
|
|
new_font = (i >= bstart && i < bend) ? user_font_get_bold() : user_font_get_regular();
|
2000-09-08 09:50:08 +00:00
|
|
|
if (cur_font != new_font) {
|
|
|
|
gtk_text_insert(bv, cur_font, NULL, NULL, line, cur);
|
|
|
|
cur_font = new_font;
|
|
|
|
cur = 0;
|
|
|
|
}
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
2000-09-08 09:50:08 +00:00
|
|
|
line[cur++] = '\n';
|
|
|
|
line[cur] = '\0';
|
|
|
|
gtk_text_insert(bv, cur_font, NULL, NULL, line, -1);
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
if (prefs.gui_hex_dump_highlight_style)
|
|
|
|
revstyle = "reverse";
|
|
|
|
else
|
|
|
|
revstyle = "bold";
|
|
|
|
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, line, -1, "plain",
|
|
|
|
NULL);
|
|
|
|
/* Do we start in reverse? */
|
|
|
|
reverse = i >= bstart && i < bend;
|
|
|
|
j = i;
|
|
|
|
k = i + BYTE_VIEW_WIDTH;
|
|
|
|
cur = 0;
|
|
|
|
/* Print the hex bit */
|
|
|
|
while (i < k) {
|
|
|
|
if (i < len) {
|
|
|
|
line[cur++] = hexchars[(pd[i] & 0xf0) >> 4];
|
|
|
|
line[cur++] = hexchars[pd[i] & 0x0f];
|
|
|
|
} else {
|
|
|
|
line[cur++] = ' '; line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
newreverse = i >= bstart && i < bend;
|
|
|
|
/* Have we gone from reverse to plain? */
|
|
|
|
if (reverse && (reverse != newreverse)) {
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, line, cur,
|
|
|
|
revstyle, NULL);
|
|
|
|
cur = 0;
|
|
|
|
}
|
|
|
|
/* Inter byte space if not at end of line */
|
|
|
|
if (i < k) {
|
|
|
|
line[cur++] = ' ';
|
|
|
|
/* insert a space every BYTE_VIEW_SEP bytes */
|
|
|
|
if( ( i % BYTE_VIEW_SEP ) == 0 ) {
|
|
|
|
line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Have we gone from plain to reversed? */
|
|
|
|
if (!reverse && (reverse != newreverse)) {
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, line, cur,
|
|
|
|
"plain", NULL);
|
|
|
|
mark = gtk_text_buffer_create_mark(buf, NULL, &iter, TRUE);
|
|
|
|
cur = 0;
|
|
|
|
}
|
|
|
|
reverse = newreverse;
|
|
|
|
}
|
|
|
|
/* Print remaining part of line */
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, line, cur,
|
|
|
|
reverse ? revstyle : "plain",
|
|
|
|
NULL);
|
|
|
|
cur = 0;
|
|
|
|
/* Print some space at the end of the line */
|
|
|
|
line[cur++] = ' '; line[cur++] = ' '; line[cur++] = ' ';
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, line, cur,
|
|
|
|
"plain", NULL);
|
|
|
|
cur = 0;
|
|
|
|
|
|
|
|
/* Print the ASCII bit */
|
|
|
|
i = j;
|
|
|
|
/* Do we start in reverse? */
|
|
|
|
reverse = i >= bstart && i < bend;
|
|
|
|
while (i < k) {
|
|
|
|
if (i < len) {
|
|
|
|
if (encoding == CHAR_ASCII) {
|
|
|
|
c = pd[i];
|
|
|
|
}
|
|
|
|
else if (encoding == CHAR_EBCDIC) {
|
|
|
|
c = EBCDIC_to_ASCII1(pd[i]);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
line[cur++] = isprint(c) ? c : '.';
|
|
|
|
} else {
|
|
|
|
line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
newreverse = i >= bstart && i < bend;
|
|
|
|
/* Have we gone from reverse to plain? */
|
|
|
|
if (reverse && (reverse != newreverse)) {
|
|
|
|
convline = g_locale_to_utf8(line, cur, NULL, &newsize, NULL);
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, convline, newsize,
|
|
|
|
revstyle, NULL);
|
|
|
|
g_free(convline);
|
|
|
|
cur = 0;
|
|
|
|
}
|
|
|
|
if (i < k) {
|
|
|
|
/* insert a space every BYTE_VIEW_SEP bytes */
|
|
|
|
if( ( i % BYTE_VIEW_SEP ) == 0 ) {
|
|
|
|
line[cur++] = ' ';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Have we gone from plain to reversed? */
|
|
|
|
if (!reverse && (reverse != newreverse)) {
|
|
|
|
convline = g_locale_to_utf8(line, cur, NULL, &newsize, NULL);
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, convline, newsize,
|
|
|
|
"plain", NULL);
|
|
|
|
g_free(convline);
|
|
|
|
cur = 0;
|
|
|
|
}
|
|
|
|
reverse = newreverse;
|
|
|
|
}
|
|
|
|
/* Print remaining part of line */
|
|
|
|
convline = g_locale_to_utf8(line, cur, NULL, &newsize, NULL);
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, convline, newsize,
|
|
|
|
reverse ? revstyle : "plain",
|
|
|
|
NULL);
|
|
|
|
g_free(convline);
|
|
|
|
cur = 0;
|
|
|
|
line[cur++] = '\n';
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, line, cur,
|
|
|
|
"plain", NULL);
|
|
|
|
#endif
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
1999-12-03 21:28:58 +00:00
|
|
|
|
2004-04-23 19:43:06 +00:00
|
|
|
/* We're done printing the packets; destroy the progress bar if
|
|
|
|
it was created. */
|
|
|
|
if (progbar != NULL)
|
|
|
|
destroy_progress_dlg(progbar);
|
|
|
|
|
1999-12-03 21:28:58 +00:00
|
|
|
/* scroll text into position */
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
1999-12-03 21:28:58 +00:00
|
|
|
gtk_text_thaw(bv); /* must thaw before adjusting scroll bars */
|
|
|
|
if ( bstart > 0 ) {
|
2001-03-23 22:26:33 +00:00
|
|
|
int linenum;
|
1999-12-14 06:52:09 +00:00
|
|
|
float scrollval;
|
1999-12-03 21:28:58 +00:00
|
|
|
|
2001-01-11 05:51:10 +00:00
|
|
|
linenum = bstart / BYTE_VIEW_WIDTH;
|
2004-06-17 16:35:26 +00:00
|
|
|
scrollval = MIN(linenum * user_font_get_regular_height(),
|
2001-03-23 22:26:33 +00:00
|
|
|
bv->vadj->upper - bv->vadj->page_size);
|
1999-12-03 21:28:58 +00:00
|
|
|
|
|
|
|
gtk_adjustment_set_value(bv->vadj, scrollval);
|
|
|
|
}
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
if (mark) {
|
|
|
|
gtk_text_view_scroll_to_mark(bv, mark, 0.0, TRUE, 1.0, 0.0);
|
|
|
|
gtk_text_buffer_delete_mark(buf, mark);
|
|
|
|
}
|
|
|
|
#endif
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2001-03-23 14:44:04 +00:00
|
|
|
void
|
2002-02-18 01:08:44 +00:00
|
|
|
packet_hex_print(GtkText *bv, const guint8 *pd, frame_data *fd,
|
|
|
|
field_info *finfo, guint len)
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
void
|
|
|
|
packet_hex_print(GtkTextView *bv, const guint8 *pd, frame_data *fd,
|
|
|
|
field_info *finfo, guint len)
|
|
|
|
#endif
|
2002-02-18 01:08:44 +00:00
|
|
|
{
|
2001-03-23 14:44:04 +00:00
|
|
|
/* do the initial printing and save the information needed */
|
|
|
|
/* to redraw the display if preferences change. */
|
|
|
|
|
|
|
|
int bstart, bend = -1, blen;
|
|
|
|
|
|
|
|
if (finfo != NULL) {
|
|
|
|
bstart = finfo->start;
|
|
|
|
blen = finfo->length;
|
|
|
|
} else {
|
|
|
|
bstart = -1;
|
|
|
|
blen = -1;
|
|
|
|
}
|
|
|
|
if (bstart >= 0 && blen >= 0) {
|
2001-03-24 23:57:12 +00:00
|
|
|
bend = bstart + blen;
|
2001-03-23 14:44:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* save the information needed to redraw the text */
|
|
|
|
/* should we save the fd & finfo pointers instead ?? */
|
2002-11-11 15:39:06 +00:00
|
|
|
OBJECT_SET_DATA(bv, E_BYTE_VIEW_START_KEY, GINT_TO_POINTER(bend));
|
|
|
|
OBJECT_SET_DATA(bv, E_BYTE_VIEW_END_KEY, GINT_TO_POINTER(bstart));
|
|
|
|
OBJECT_SET_DATA(bv, E_BYTE_VIEW_ENCODE_KEY,
|
|
|
|
GINT_TO_POINTER(fd->flags.encoding));
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
packet_hex_print_common(bv, pd, len, bstart, bend, fd->flags.encoding);
|
2001-03-23 14:44:04 +00:00
|
|
|
}
|
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/*
|
|
|
|
* Redraw the text using the saved information; usually called if
|
|
|
|
* the preferences have changed.
|
|
|
|
*/
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2001-03-23 14:44:04 +00:00
|
|
|
void
|
2002-02-18 01:08:44 +00:00
|
|
|
packet_hex_reprint(GtkText *bv)
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
void
|
|
|
|
packet_hex_reprint(GtkTextView *bv)
|
|
|
|
#endif
|
2002-02-18 01:08:44 +00:00
|
|
|
{
|
|
|
|
int start, end, encoding;
|
|
|
|
const guint8 *data;
|
|
|
|
guint len;
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-11-11 15:39:06 +00:00
|
|
|
start = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_START_KEY));
|
|
|
|
end = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_END_KEY));
|
2002-02-18 01:08:44 +00:00
|
|
|
data = get_byte_view_data_and_length(GTK_WIDGET(bv), &len);
|
|
|
|
g_assert(data != NULL);
|
2002-11-11 15:39:06 +00:00
|
|
|
encoding = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_ENCODE_KEY));
|
2001-03-23 14:44:04 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
packet_hex_print_common(bv, data, len, start, end, encoding);
|
2001-03-23 14:44:04 +00:00
|
|
|
}
|
|
|
|
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
/* List of all protocol tree widgets, so we can globally set the selection
|
2002-01-11 06:43:18 +00:00
|
|
|
mode and font of all of them. */
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
static GList *ptree_widgets;
|
|
|
|
|
|
|
|
/* Add a protocol tree widget to the list of protocol tree widgets. */
|
|
|
|
static void forget_ptree_widget(GtkWidget *ptreew, gpointer data);
|
|
|
|
|
2000-09-08 09:50:08 +00:00
|
|
|
static void
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
remember_ptree_widget(GtkWidget *ptreew)
|
|
|
|
{
|
|
|
|
ptree_widgets = g_list_append(ptree_widgets, ptreew);
|
|
|
|
|
|
|
|
/* Catch the "destroy" event on the widget, so that we remove it from
|
|
|
|
the list when it's destroyed. */
|
2002-11-11 15:39:06 +00:00
|
|
|
SIGNAL_CONNECT(ptreew, "destroy", forget_ptree_widget, NULL);
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
}
|
|
|
|
|
2000-09-08 09:50:08 +00:00
|
|
|
/* Remove a protocol tree widget from the list of protocol tree widgets. */
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
static void
|
2002-03-05 11:56:00 +00:00
|
|
|
forget_ptree_widget(GtkWidget *ptreew, gpointer data _U_)
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
{
|
|
|
|
ptree_widgets = g_list_remove(ptree_widgets, ptreew);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the selection mode of a given packet tree window. */
|
|
|
|
static void
|
2002-11-03 17:38:45 +00:00
|
|
|
set_ptree_sel_browse(GtkWidget *tree, gboolean val)
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
{
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
GtkTreeSelection *selection;
|
|
|
|
|
|
|
|
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
|
|
|
|
#endif
|
|
|
|
/* 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) {
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
gtk_clist_set_selection_mode(GTK_CLIST(tree),
|
|
|
|
GTK_SELECTION_SINGLE);
|
|
|
|
#else
|
|
|
|
gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
gtk_clist_set_selection_mode(GTK_CLIST(tree),
|
|
|
|
GTK_SELECTION_BROWSE);
|
|
|
|
#else
|
|
|
|
gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
|
|
|
|
#endif
|
|
|
|
}
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
set_ptree_sel_browse_cb(gpointer data, gpointer user_data)
|
|
|
|
{
|
|
|
|
set_ptree_sel_browse((GtkWidget *)data, *(gboolean *)user_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the selection mode of all packet tree windows. */
|
|
|
|
void
|
|
|
|
set_ptree_sel_browse_all(gboolean val)
|
|
|
|
{
|
|
|
|
g_list_foreach(ptree_widgets, set_ptree_sel_browse_cb, &val);
|
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
static void
|
|
|
|
set_ptree_style_cb(gpointer data, gpointer user_data)
|
|
|
|
{
|
|
|
|
gtk_widget_set_style((GtkWidget *)data, (GtkStyle *)user_data);
|
|
|
|
}
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
static void
|
|
|
|
set_ptree_font_cb(gpointer data, gpointer user_data)
|
|
|
|
{
|
|
|
|
gtk_widget_modify_font((GtkWidget *)data,
|
|
|
|
(PangoFontDescription *)user_data);
|
|
|
|
}
|
|
|
|
#endif
|
2002-08-28 21:04:11 +00:00
|
|
|
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
void
|
2004-06-17 16:35:26 +00:00
|
|
|
set_ptree_font_all(FONT_TYPE *font)
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
{
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
GtkStyle *style;
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
style = gtk_style_new();
|
|
|
|
gdk_font_unref(style->font);
|
|
|
|
style->font = font;
|
|
|
|
gdk_font_ref(font);
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
g_list_foreach(ptree_widgets, set_ptree_style_cb, style);
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/* Now nuke the old style and replace it with the new one. */
|
|
|
|
gtk_style_unref(item_style);
|
|
|
|
item_style = style;
|
|
|
|
#else
|
|
|
|
g_list_foreach(ptree_widgets, set_ptree_font_cb, font);
|
|
|
|
#endif
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
}
|
|
|
|
|
2004-05-14 15:55:37 +00:00
|
|
|
|
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
2004-05-21 00:18:46 +00:00
|
|
|
void tree_cell_renderer(GtkTreeViewColumn *tree_column _U_,
|
2004-05-14 15:55:37 +00:00
|
|
|
GtkCellRenderer *cell,
|
|
|
|
GtkTreeModel *tree_model,
|
|
|
|
GtkTreeIter *iter,
|
2004-05-21 00:18:46 +00:00
|
|
|
gpointer data _U_)
|
2004-05-14 15:55:37 +00:00
|
|
|
{
|
|
|
|
field_info *fi;
|
|
|
|
|
|
|
|
gtk_tree_model_get(tree_model, iter, 1, &fi, -1);
|
|
|
|
|
|
|
|
/* for each field, we have to reset the renderer attributes */
|
|
|
|
g_object_set (cell, "foreground-set", FALSE, NULL);
|
|
|
|
|
|
|
|
g_object_set (cell, "underline", PANGO_UNDERLINE_NONE, NULL);
|
|
|
|
g_object_set (cell, "underline-set", FALSE, NULL);
|
|
|
|
|
|
|
|
/*g_object_set (cell, "style", PANGO_STYLE_NORMAL, NULL);
|
|
|
|
g_object_set (cell, "style-set", FALSE, NULL);*/
|
|
|
|
|
|
|
|
/*g_object_set (cell, "weight", PANGO_WEIGHT_NORMAL, NULL);
|
|
|
|
g_object_set (cell, "weight-set", FALSE, NULL);*/
|
|
|
|
|
|
|
|
if(FI_GET_FLAG(fi, FI_GENERATED)) {
|
|
|
|
/* as some fonts don't support italic, don't use this */
|
|
|
|
/*g_object_set (cell, "style", PANGO_STYLE_ITALIC, NULL);
|
|
|
|
g_object_set (cell, "style-set", TRUE, NULL);
|
|
|
|
*/
|
|
|
|
/*g_object_set (cell, "weight", PANGO_WEIGHT_BOLD, NULL);
|
|
|
|
g_object_set (cell, "weight-set", TRUE, NULL);*/
|
|
|
|
}
|
|
|
|
|
2004-05-15 00:41:27 +00:00
|
|
|
if(fi->hfinfo->type == FT_FRAMENUM) {
|
2004-05-14 15:55:37 +00:00
|
|
|
g_object_set (cell, "foreground", "blue", NULL);
|
|
|
|
g_object_set (cell, "foreground-set", TRUE, NULL);
|
|
|
|
|
|
|
|
g_object_set (cell, "underline", PANGO_UNDERLINE_SINGLE, NULL);
|
|
|
|
g_object_set (cell, "underline-set", TRUE, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2004-01-19 00:42:12 +00:00
|
|
|
GtkWidget *
|
|
|
|
main_tree_view_new(e_prefs *prefs, GtkWidget **tree_view_p)
|
2000-02-29 06:24:41 +00:00
|
|
|
{
|
|
|
|
GtkWidget *tv_scrollw, *tree_view;
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
GtkTreeStore *store;
|
|
|
|
GtkCellRenderer *renderer;
|
|
|
|
GtkTreeViewColumn *column;
|
|
|
|
gint col_offset;
|
|
|
|
#endif
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
/* Tree view */
|
2002-01-11 07:40:32 +00:00
|
|
|
tv_scrollw = scrolled_window_new(NULL, NULL);
|
2004-02-06 19:19:12 +00:00
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(tv_scrollw),
|
|
|
|
GTK_SHADOW_IN);
|
2002-11-03 17:38:45 +00:00
|
|
|
#endif
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2002-01-11 06:43:18 +00:00
|
|
|
tree_view = ctree_new(1, 0);
|
2002-11-11 15:39:06 +00:00
|
|
|
SIGNAL_CONNECT(tree_view, "key-press-event", toggle_tree, NULL );
|
|
|
|
SIGNAL_CONNECT(tree_view, "tree-expand", expand_tree, NULL );
|
|
|
|
SIGNAL_CONNECT(tree_view, "tree-collapse", collapse_tree, NULL );
|
2000-02-29 06:24:41 +00:00
|
|
|
/* 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 );
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
|
|
|
|
tree_view = tree_view_new(GTK_TREE_MODEL(store));
|
|
|
|
g_object_unref(G_OBJECT(store));
|
|
|
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), FALSE);
|
|
|
|
renderer = gtk_cell_renderer_text_new();
|
2004-05-14 15:55:37 +00:00
|
|
|
g_object_set (renderer, "ypad", 0, NULL);
|
2002-11-03 17:38:45 +00:00
|
|
|
col_offset = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree_view),
|
|
|
|
-1, "Name", renderer,
|
|
|
|
"text", 0, NULL);
|
|
|
|
column = gtk_tree_view_get_column(GTK_TREE_VIEW(tree_view),
|
|
|
|
col_offset - 1);
|
2004-05-14 15:55:37 +00:00
|
|
|
gtk_tree_view_column_set_cell_data_func(column,
|
|
|
|
renderer,
|
|
|
|
tree_cell_renderer,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
|
|
|
|
GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
2002-11-11 15:39:06 +00:00
|
|
|
SIGNAL_CONNECT(tree_view, "row-expanded", expand_tree, NULL);
|
|
|
|
SIGNAL_CONNECT(tree_view, "row-collapsed", collapse_tree, NULL);
|
2002-11-03 17:38:45 +00:00
|
|
|
#endif
|
2000-02-29 06:24:41 +00:00
|
|
|
gtk_container_add( GTK_CONTAINER(tv_scrollw), tree_view );
|
|
|
|
set_ptree_sel_browse(tree_view, prefs->gui_ptree_sel_browse);
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2004-06-17 16:35:26 +00:00
|
|
|
if(item_style == NULL) {
|
|
|
|
item_style = gtk_style_new();
|
|
|
|
gdk_font_unref(item_style->font);
|
|
|
|
item_style->font = user_font_get_regular();
|
|
|
|
}
|
|
|
|
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
gtk_widget_set_style(tree_view, item_style);
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
2004-06-17 16:35:26 +00:00
|
|
|
gtk_widget_modify_font(tree_view, user_font_get_regular());
|
2002-11-03 17:38:45 +00:00
|
|
|
#endif
|
Instead of each set of built-in preferences having "ok", "save",
"cancel", and "delete" methods, give them:
"fetch" - fetch from the notebook tab any values not already
stored in "prefs", and store them there, but doesn't apply them;
"apply" - apply the settings in "prefs";
"destroy" - clean up any windows created from the tab.
As we no longer have "cancel" methods, we don't have per-preference code
to revert preference values; instead, we have the common preference
dialog box code make a copy of all the current preferences, and, when
the "Cancel" button is clicked, free the current preferences and copy
the saved preferences to it, and apply the preferences.
Add an "Apply" button to the preference dialog box, which applies the
current preferences without closing the dialog box.
Treat a request to delete the preferences dialog box as equivalent to
clicking "Cancel".
Have a "remember_ptree_widget()" routine to remember all protocol tree
widgets, and use the list of those widgets when we set GUI preferences
for the protocol tree widgets, rather than setting the main protocol
tree widget and then using the list of packet windows. Move that code
out of "main.c" to "proto_draw.c", as it's not used by anything in
"main.c", but is used by stuff in "proto_draw.c".
Make the font one of the preferences we can set on the fly for protocol
tree widgets. Also make it something we can set on the fly for the
packet list widget.
svn path=/trunk/; revision=2316
2000-08-21 08:09:17 +00:00
|
|
|
remember_ptree_widget(tree_view);
|
2000-02-29 06:24:41 +00:00
|
|
|
|
|
|
|
*tree_view_p = tree_view;
|
2004-01-19 00:42:12 +00:00
|
|
|
|
|
|
|
return tv_scrollw;
|
2000-02-29 06:24:41 +00:00
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
void expand_all_tree(proto_tree *protocol_tree, GtkWidget *tree_view)
|
|
|
|
#else
|
|
|
|
void expand_all_tree(proto_tree *protocol_tree _U_, GtkWidget *tree_view)
|
|
|
|
#endif
|
|
|
|
{
|
1999-09-11 12:38:18 +00:00
|
|
|
int i;
|
1999-11-16 11:44:20 +00:00
|
|
|
for(i=0; i < num_tree_types; i++) {
|
1999-09-12 20:23:43 +00:00
|
|
|
tree_is_expanded[i] = TRUE;
|
1999-09-11 12:38:18 +00:00
|
|
|
}
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
1999-09-11 12:38:18 +00:00
|
|
|
proto_tree_draw(protocol_tree, tree_view);
|
Changed the protocol tree widget from a GtkTree to a GtkCTree. The two reasons
I did this:
First, Havoc Pennington, in "GTK+/Gnome Application Development", in
Appendix seciton A.3.88, recommends using GtkCTree instead of GtkTree
because GtkCtree is faster, and GtkTree has limitation on its total row
height: since it must fit inside a GdkWindow, it is limited to 32,768
pixels of height. GtkTree is more flexible with regards to the types of
widgets that can be placed in the tree, but since we deal only with text,
that doesn't matter, at least for now.
Secondly, a GtkTree doesn't allow arrow-key navigation (at least as far
as I could tell). It always bothered me that the up and down arrow keys
worked in the packet list and in the hex dump, but no in the protocol tree.
GtkCTree does allow arrow-key navigation. In fact, GtkCTree is a subclass
of GtkCList (the packet list widget), so they behave a lot alike.
I went ahead and fixed the selection bar which has been bothering Richard
for a long time now. :) In the GUI preferences dialogue, you can now set
both the packet list selection bar and the protocol tree selection bar
to either "browse" or "select" mode. "browse" mode is what you're used to:
the arrow keys move an outline of the selection bar, but do not change
the selection. "select" mode does change the selection when the arrow keys
are pressed. The default behavior is set to "select", which seems more
natural for a first-time user.
svn path=/trunk/; revision=1393
1999-12-29 20:10:12 +00:00
|
|
|
gtk_ctree_expand_recursive(GTK_CTREE(tree_view), NULL);
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
gtk_tree_view_expand_all(GTK_TREE_VIEW(tree_view));
|
|
|
|
#endif
|
1999-09-11 12:38:18 +00:00
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
void collapse_all_tree(proto_tree *protocol_tree, GtkWidget *tree_view)
|
|
|
|
#else
|
|
|
|
void collapse_all_tree(proto_tree *protocol_tree _U_, GtkWidget *tree_view)
|
|
|
|
#endif
|
|
|
|
{
|
1999-09-11 12:38:18 +00:00
|
|
|
int i;
|
1999-11-16 11:44:20 +00:00
|
|
|
for(i=0; i < num_tree_types; i++) {
|
1999-09-12 20:23:43 +00:00
|
|
|
tree_is_expanded[i] = FALSE;
|
1999-09-11 12:38:18 +00:00
|
|
|
}
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
1999-12-15 07:03:11 +00:00
|
|
|
proto_tree_draw(protocol_tree, tree_view);
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree_view));
|
|
|
|
#endif
|
1999-09-11 12:38:18 +00:00
|
|
|
}
|
|
|
|
|
1999-03-23 03:14:46 +00:00
|
|
|
|
Changed the protocol tree widget from a GtkTree to a GtkCTree. The two reasons
I did this:
First, Havoc Pennington, in "GTK+/Gnome Application Development", in
Appendix seciton A.3.88, recommends using GtkCTree instead of GtkTree
because GtkCtree is faster, and GtkTree has limitation on its total row
height: since it must fit inside a GdkWindow, it is limited to 32,768
pixels of height. GtkTree is more flexible with regards to the types of
widgets that can be placed in the tree, but since we deal only with text,
that doesn't matter, at least for now.
Secondly, a GtkTree doesn't allow arrow-key navigation (at least as far
as I could tell). It always bothered me that the up and down arrow keys
worked in the packet list and in the hex dump, but no in the protocol tree.
GtkCTree does allow arrow-key navigation. In fact, GtkCTree is a subclass
of GtkCList (the packet list widget), so they behave a lot alike.
I went ahead and fixed the selection bar which has been bothering Richard
for a long time now. :) In the GUI preferences dialogue, you can now set
both the packet list selection bar and the protocol tree selection bar
to either "browse" or "select" mode. "browse" mode is what you're used to:
the arrow keys move an outline of the selection bar, but do not change
the selection. "select" mode does change the selection when the arrow keys
are pressed. The default behavior is set to "select", which seems more
natural for a first-time user.
svn path=/trunk/; revision=1393
1999-12-29 20:10:12 +00:00
|
|
|
struct proto_tree_draw_info {
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
GtkCTree *ctree;
|
|
|
|
GtkCTreeNode *ctree_node;
|
|
|
|
#else
|
|
|
|
GtkTreeView *tree_view;
|
|
|
|
GtkTreeIter *iter;
|
|
|
|
#endif
|
Changed the protocol tree widget from a GtkTree to a GtkCTree. The two reasons
I did this:
First, Havoc Pennington, in "GTK+/Gnome Application Development", in
Appendix seciton A.3.88, recommends using GtkCTree instead of GtkTree
because GtkCtree is faster, and GtkTree has limitation on its total row
height: since it must fit inside a GdkWindow, it is limited to 32,768
pixels of height. GtkTree is more flexible with regards to the types of
widgets that can be placed in the tree, but since we deal only with text,
that doesn't matter, at least for now.
Secondly, a GtkTree doesn't allow arrow-key navigation (at least as far
as I could tell). It always bothered me that the up and down arrow keys
worked in the packet list and in the hex dump, but no in the protocol tree.
GtkCTree does allow arrow-key navigation. In fact, GtkCTree is a subclass
of GtkCList (the packet list widget), so they behave a lot alike.
I went ahead and fixed the selection bar which has been bothering Richard
for a long time now. :) In the GUI preferences dialogue, you can now set
both the packet list selection bar and the protocol tree selection bar
to either "browse" or "select" mode. "browse" mode is what you're used to:
the arrow keys move an outline of the selection bar, but do not change
the selection. "select" mode does change the selection when the arrow keys
are pressed. The default behavior is set to "select", which seems more
natural for a first-time user.
svn path=/trunk/; revision=1393
1999-12-29 20:10:12 +00:00
|
|
|
};
|
|
|
|
|
2002-09-21 11:36:30 +00:00
|
|
|
void
|
|
|
|
main_proto_tree_draw(proto_tree *protocol_tree)
|
|
|
|
{
|
|
|
|
proto_tree_draw(protocol_tree, tree_view);
|
|
|
|
}
|
|
|
|
|
2004-05-14 15:55:37 +00:00
|
|
|
|
|
|
|
void
|
2004-05-14 18:02:38 +00:00
|
|
|
tree_view_follow_link(field_info *fi)
|
2004-05-14 15:55:37 +00:00
|
|
|
{
|
2004-05-15 00:41:27 +00:00
|
|
|
if(fi->hfinfo->type == FT_FRAMENUM) {
|
2005-02-04 18:44:44 +00:00
|
|
|
cf_goto_frame(&cfile, fi->value.value.integer);
|
2004-05-14 15:55:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-27 19:46:52 +00:00
|
|
|
/* If the user selected a position in the tree view, try to find
|
|
|
|
* the item in the GUI proto_tree that corresponds to that byte, and
|
|
|
|
* select it. */
|
2004-01-27 20:36:48 +00:00
|
|
|
gboolean
|
2004-01-27 19:46:52 +00:00
|
|
|
tree_view_select(GtkWidget *widget, GdkEventButton *event)
|
|
|
|
{
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
GtkCTree *ctree;
|
|
|
|
GtkCTreeNode *node;
|
|
|
|
gint row;
|
|
|
|
gint column;
|
2004-05-14 18:02:38 +00:00
|
|
|
field_info *fi;
|
2004-01-27 19:46:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
if(gtk_clist_get_selection_info(GTK_CLIST(widget),
|
|
|
|
(gint) (((GdkEventButton *)event)->x),
|
|
|
|
(gint) (((GdkEventButton *)event)->y),
|
|
|
|
&row, &column))
|
|
|
|
{
|
|
|
|
ctree = GTK_CTREE(widget);
|
|
|
|
|
|
|
|
node = gtk_ctree_node_nth(ctree, row);
|
|
|
|
g_assert(node);
|
|
|
|
|
|
|
|
gtk_ctree_select(ctree, node);
|
2004-05-14 18:02:38 +00:00
|
|
|
|
|
|
|
/* if that's a doubleclick, try to follow the link */
|
|
|
|
if(event->type == GDK_2BUTTON_PRESS) {
|
|
|
|
fi = gtk_ctree_node_get_row_data(ctree, node);
|
|
|
|
tree_view_follow_link(fi);
|
|
|
|
}
|
2004-01-27 19:46:52 +00:00
|
|
|
} else {
|
2004-01-27 20:58:19 +00:00
|
|
|
return FALSE;
|
2004-01-27 19:46:52 +00:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
GtkTreeSelection *sel;
|
|
|
|
GtkTreePath *path;
|
|
|
|
|
|
|
|
if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget),
|
|
|
|
(gint) (((GdkEventButton *)event)->x),
|
|
|
|
(gint) (((GdkEventButton *)event)->y),
|
|
|
|
&path, NULL, NULL, NULL))
|
|
|
|
{
|
|
|
|
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
|
|
|
|
gtk_tree_selection_select_path(sel, path);
|
2004-05-14 15:55:37 +00:00
|
|
|
|
|
|
|
/* if that's a doubleclick, try to follow the link */
|
|
|
|
if(event->type == GDK_2BUTTON_PRESS) {
|
2004-05-14 18:02:38 +00:00
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
field_info *fi;
|
|
|
|
|
|
|
|
if(gtk_tree_selection_get_selected (sel, &model, &iter)) {
|
|
|
|
gtk_tree_model_get(model, &iter, 1, &fi, -1);
|
|
|
|
tree_view_follow_link(fi);
|
|
|
|
}
|
2004-05-14 15:55:37 +00:00
|
|
|
}
|
2004-01-27 19:46:52 +00:00
|
|
|
} else {
|
2004-01-27 20:58:19 +00:00
|
|
|
return FALSE;
|
2004-01-27 19:46:52 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1999-03-23 03:14:46 +00:00
|
|
|
void
|
1999-07-07 22:52:57 +00:00
|
|
|
proto_tree_draw(proto_tree *protocol_tree, GtkWidget *tree_view)
|
1999-03-23 03:14:46 +00:00
|
|
|
{
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
GtkTreeStore *store;
|
|
|
|
#endif
|
|
|
|
struct proto_tree_draw_info info;
|
Changed the protocol tree widget from a GtkTree to a GtkCTree. The two reasons
I did this:
First, Havoc Pennington, in "GTK+/Gnome Application Development", in
Appendix seciton A.3.88, recommends using GtkCTree instead of GtkTree
because GtkCtree is faster, and GtkTree has limitation on its total row
height: since it must fit inside a GdkWindow, it is limited to 32,768
pixels of height. GtkTree is more flexible with regards to the types of
widgets that can be placed in the tree, but since we deal only with text,
that doesn't matter, at least for now.
Secondly, a GtkTree doesn't allow arrow-key navigation (at least as far
as I could tell). It always bothered me that the up and down arrow keys
worked in the packet list and in the hex dump, but no in the protocol tree.
GtkCTree does allow arrow-key navigation. In fact, GtkCTree is a subclass
of GtkCList (the packet list widget), so they behave a lot alike.
I went ahead and fixed the selection bar which has been bothering Richard
for a long time now. :) In the GUI preferences dialogue, you can now set
both the packet list selection bar and the protocol tree selection bar
to either "browse" or "select" mode. "browse" mode is what you're used to:
the arrow keys move an outline of the selection bar, but do not change
the selection. "select" mode does change the selection when the arrow keys
are pressed. The default behavior is set to "select", which seems more
natural for a first-time user.
svn path=/trunk/; revision=1393
1999-12-29 20:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
info.ctree = GTK_CTREE(tree_view);
|
|
|
|
info.ctree_node = NULL;
|
Changed the protocol tree widget from a GtkTree to a GtkCTree. The two reasons
I did this:
First, Havoc Pennington, in "GTK+/Gnome Application Development", in
Appendix seciton A.3.88, recommends using GtkCTree instead of GtkTree
because GtkCtree is faster, and GtkTree has limitation on its total row
height: since it must fit inside a GdkWindow, it is limited to 32,768
pixels of height. GtkTree is more flexible with regards to the types of
widgets that can be placed in the tree, but since we deal only with text,
that doesn't matter, at least for now.
Secondly, a GtkTree doesn't allow arrow-key navigation (at least as far
as I could tell). It always bothered me that the up and down arrow keys
worked in the packet list and in the hex dump, but no in the protocol tree.
GtkCTree does allow arrow-key navigation. In fact, GtkCTree is a subclass
of GtkCList (the packet list widget), so they behave a lot alike.
I went ahead and fixed the selection bar which has been bothering Richard
for a long time now. :) In the GUI preferences dialogue, you can now set
both the packet list selection bar and the protocol tree selection bar
to either "browse" or "select" mode. "browse" mode is what you're used to:
the arrow keys move an outline of the selection bar, but do not change
the selection. "select" mode does change the selection when the arrow keys
are pressed. The default behavior is set to "select", which seems more
natural for a first-time user.
svn path=/trunk/; revision=1393
1999-12-29 20:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
gtk_clist_freeze(GTK_CLIST(tree_view));
|
|
|
|
#else
|
|
|
|
info.tree_view = GTK_TREE_VIEW(tree_view);
|
|
|
|
info.iter = NULL;
|
2002-02-18 01:08:44 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)));
|
|
|
|
#endif
|
Changed the protocol tree widget from a GtkTree to a GtkCTree. The two reasons
I did this:
First, Havoc Pennington, in "GTK+/Gnome Application Development", in
Appendix seciton A.3.88, recommends using GtkCTree instead of GtkTree
because GtkCtree is faster, and GtkTree has limitation on its total row
height: since it must fit inside a GdkWindow, it is limited to 32,768
pixels of height. GtkTree is more flexible with regards to the types of
widgets that can be placed in the tree, but since we deal only with text,
that doesn't matter, at least for now.
Secondly, a GtkTree doesn't allow arrow-key navigation (at least as far
as I could tell). It always bothered me that the up and down arrow keys
worked in the packet list and in the hex dump, but no in the protocol tree.
GtkCTree does allow arrow-key navigation. In fact, GtkCTree is a subclass
of GtkCList (the packet list widget), so they behave a lot alike.
I went ahead and fixed the selection bar which has been bothering Richard
for a long time now. :) In the GUI preferences dialogue, you can now set
both the packet list selection bar and the protocol tree selection bar
to either "browse" or "select" mode. "browse" mode is what you're used to:
the arrow keys move an outline of the selection bar, but do not change
the selection. "select" mode does change the selection when the arrow keys
are pressed. The default behavior is set to "select", which seems more
natural for a first-time user.
svn path=/trunk/; revision=1393
1999-12-29 20:10:12 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/*
|
|
|
|
* Clear out any crud left over in the display of the protocol
|
|
|
|
* tree, by removing all nodes from the tree.
|
|
|
|
* This is how it's done in testgtk.c in GTK+.
|
|
|
|
*/
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
gtk_clist_clear(GTK_CLIST(tree_view));
|
|
|
|
#else
|
|
|
|
gtk_tree_store_clear(store);
|
|
|
|
#endif
|
Changed the protocol tree widget from a GtkTree to a GtkCTree. The two reasons
I did this:
First, Havoc Pennington, in "GTK+/Gnome Application Development", in
Appendix seciton A.3.88, recommends using GtkCTree instead of GtkTree
because GtkCtree is faster, and GtkTree has limitation on its total row
height: since it must fit inside a GdkWindow, it is limited to 32,768
pixels of height. GtkTree is more flexible with regards to the types of
widgets that can be placed in the tree, but since we deal only with text,
that doesn't matter, at least for now.
Secondly, a GtkTree doesn't allow arrow-key navigation (at least as far
as I could tell). It always bothered me that the up and down arrow keys
worked in the packet list and in the hex dump, but no in the protocol tree.
GtkCTree does allow arrow-key navigation. In fact, GtkCTree is a subclass
of GtkCList (the packet list widget), so they behave a lot alike.
I went ahead and fixed the selection bar which has been bothering Richard
for a long time now. :) In the GUI preferences dialogue, you can now set
both the packet list selection bar and the protocol tree selection bar
to either "browse" or "select" mode. "browse" mode is what you're used to:
the arrow keys move an outline of the selection bar, but do not change
the selection. "select" mode does change the selection when the arrow keys
are pressed. The default behavior is set to "select", which seems more
natural for a first-time user.
svn path=/trunk/; revision=1393
1999-12-29 20:10:12 +00:00
|
|
|
|
2003-12-04 10:59:34 +00:00
|
|
|
proto_tree_children_foreach(protocol_tree, proto_tree_draw_node, &info);
|
2003-11-03 21:00:05 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
gtk_clist_thaw(GTK_CLIST(tree_view));
|
|
|
|
#endif
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
static void
|
2003-12-04 10:59:34 +00:00
|
|
|
proto_tree_draw_node(proto_node *node, gpointer data)
|
1999-03-23 03:14:46 +00:00
|
|
|
{
|
2002-11-03 17:38:45 +00:00
|
|
|
struct proto_tree_draw_info info;
|
|
|
|
struct proto_tree_draw_info *parent_info = (struct proto_tree_draw_info*) data;
|
|
|
|
|
|
|
|
field_info *fi = PITEM_FINFO(node);
|
|
|
|
gchar label_str[ITEM_LABEL_LENGTH];
|
|
|
|
gchar *label_ptr;
|
|
|
|
gboolean is_leaf, is_expanded;
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
GtkCTreeNode *parent;
|
|
|
|
#else
|
|
|
|
GtkTreeStore *store;
|
|
|
|
GtkTreeIter iter;
|
2003-11-03 21:00:05 +00:00
|
|
|
GtkTreePath *path;
|
2002-11-03 17:38:45 +00:00
|
|
|
#endif
|
1999-07-07 22:52:57 +00:00
|
|
|
|
2004-05-01 15:15:08 +00:00
|
|
|
if (PROTO_ITEM_IS_HIDDEN(node))
|
2002-11-03 17:38:45 +00:00
|
|
|
return;
|
1999-12-15 06:53:36 +00:00
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
/* was a free format label produced? */
|
2003-11-25 14:07:45 +00:00
|
|
|
if (fi->rep) {
|
|
|
|
label_ptr = fi->rep->representation;
|
2002-11-03 17:38:45 +00:00
|
|
|
}
|
|
|
|
else { /* no, make a generic label */
|
|
|
|
label_ptr = label_str;
|
|
|
|
proto_item_fill_label(fi, label_str);
|
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2003-12-04 10:59:34 +00:00
|
|
|
if (node->first_child != NULL) {
|
2002-11-03 17:38:45 +00:00
|
|
|
is_leaf = FALSE;
|
|
|
|
g_assert(fi->tree_type >= 0 && fi->tree_type < num_tree_types);
|
|
|
|
if (tree_is_expanded[fi->tree_type]) {
|
|
|
|
is_expanded = TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
is_expanded = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
is_leaf = TRUE;
|
|
|
|
is_expanded = FALSE;
|
|
|
|
}
|
Changed the protocol tree widget from a GtkTree to a GtkCTree. The two reasons
I did this:
First, Havoc Pennington, in "GTK+/Gnome Application Development", in
Appendix seciton A.3.88, recommends using GtkCTree instead of GtkTree
because GtkCtree is faster, and GtkTree has limitation on its total row
height: since it must fit inside a GdkWindow, it is limited to 32,768
pixels of height. GtkTree is more flexible with regards to the types of
widgets that can be placed in the tree, but since we deal only with text,
that doesn't matter, at least for now.
Secondly, a GtkTree doesn't allow arrow-key navigation (at least as far
as I could tell). It always bothered me that the up and down arrow keys
worked in the packet list and in the hex dump, but no in the protocol tree.
GtkCTree does allow arrow-key navigation. In fact, GtkCTree is a subclass
of GtkCList (the packet list widget), so they behave a lot alike.
I went ahead and fixed the selection bar which has been bothering Richard
for a long time now. :) In the GUI preferences dialogue, you can now set
both the packet list selection bar and the protocol tree selection bar
to either "browse" or "select" mode. "browse" mode is what you're used to:
the arrow keys move an outline of the selection bar, but do not change
the selection. "select" mode does change the selection when the arrow keys
are pressed. The default behavior is set to "select", which seems more
natural for a first-time user.
svn path=/trunk/; revision=1393
1999-12-29 20:10:12 +00:00
|
|
|
|
2004-05-01 15:15:08 +00:00
|
|
|
if(PROTO_ITEM_IS_GENERATED(node)) {
|
|
|
|
label_ptr = g_strdup_printf("[%s]", label_ptr);
|
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
info.ctree = parent_info->ctree;
|
|
|
|
parent = gtk_ctree_insert_node ( info.ctree, parent_info->ctree_node, NULL,
|
|
|
|
&label_ptr, 5, NULL, NULL, NULL, NULL,
|
|
|
|
is_leaf, is_expanded );
|
|
|
|
|
|
|
|
gtk_ctree_node_set_row_data( GTK_CTREE(info.ctree), parent, fi );
|
|
|
|
#else
|
|
|
|
info.tree_view = parent_info->tree_view;
|
|
|
|
store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(info.tree_view)));
|
|
|
|
gtk_tree_store_append(store, &iter, parent_info->iter);
|
|
|
|
gtk_tree_store_set(store, &iter, 0, label_ptr, 1, fi, -1);
|
|
|
|
#endif
|
1999-07-07 22:52:57 +00:00
|
|
|
|
2004-05-01 15:15:08 +00:00
|
|
|
if(PROTO_ITEM_IS_GENERATED(node)) {
|
|
|
|
g_free(label_ptr);
|
|
|
|
}
|
|
|
|
|
2002-11-03 17:38:45 +00:00
|
|
|
if (!is_leaf) {
|
|
|
|
#if GTK_MAJOR_VERSION < 2
|
|
|
|
info.ctree_node = parent;
|
|
|
|
#else
|
|
|
|
info.iter = &iter;
|
|
|
|
#endif
|
2003-12-04 10:59:34 +00:00
|
|
|
proto_tree_children_foreach(node, proto_tree_draw_node, &info);
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION >= 2
|
|
|
|
path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
|
2003-11-03 21:00:05 +00:00
|
|
|
if (is_expanded)
|
|
|
|
/* #if GTK_MINOR_VERSION >= 2 */
|
|
|
|
gtk_tree_view_expand_to_path(info.tree_view, path);
|
|
|
|
/*#else
|
|
|
|
gtk_tree_view_expand_row(info.tree_view, path, FALSE);
|
|
|
|
#endif*/
|
|
|
|
else
|
|
|
|
gtk_tree_view_collapse_row(info.tree_view, path);
|
2002-11-03 17:38:45 +00:00
|
|
|
gtk_tree_path_free(path);
|
|
|
|
#endif
|
2003-11-03 21:00:05 +00:00
|
|
|
}
|
1999-03-23 03:14:46 +00:00
|
|
|
}
|
Enable "Match Selected" only if there's a field selected *and* we can do
a "Match Selected" on it - we can't do a "Match Selected" if the field
has no value (e.g., FT_NULL) and has a length of 0.
If we unselect the current packet, we don't have a protocol tree, so we
don't have a currently selected field - clear the "Match Selected" menu
item and the display in the status line of information about the
currently selected field.
Move the low-level statusbar manipulation into "gtk/main.c", in routines
whose API doesn't expose anything GTK+-ish.
"close_cap_file()" calls one of those routines to clear out the status
bar, so it doesn't need to take a pointer to the statusbar widget as an
argument.
"clear_tree_and_hex_views()" is purely a display-manipulating routine;
move it to "gtk/proto_draw.c".
Extract from "tree_view_unselect_row_cb()" an "unselect_field()" routine
to do all the work that needs to be done if the currently selected
protocol tree row is unselected, and call it if the currently selected
packet list row is unselected (if it's unselected, there *is* no
protocol tree, so no row can be selected), as well as from
"tree_view_unselect_row_cb()".
Before pushing a new field-description message onto the statusbar, pop
the old one off.
Get rid of an unused variable (set, but not used).
svn path=/trunk/; revision=3513
2001-06-05 07:39:31 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Clear the hex dump and protocol tree panes.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clear_tree_and_hex_views(void)
|
|
|
|
{
|
2002-02-18 01:08:44 +00:00
|
|
|
/* Clear the hex dump by getting rid of all the byte views. */
|
|
|
|
while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr), 0) != NULL)
|
|
|
|
gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr), 0);
|
Enable "Match Selected" only if there's a field selected *and* we can do
a "Match Selected" on it - we can't do a "Match Selected" if the field
has no value (e.g., FT_NULL) and has a length of 0.
If we unselect the current packet, we don't have a protocol tree, so we
don't have a currently selected field - clear the "Match Selected" menu
item and the display in the status line of information about the
currently selected field.
Move the low-level statusbar manipulation into "gtk/main.c", in routines
whose API doesn't expose anything GTK+-ish.
"close_cap_file()" calls one of those routines to clear out the status
bar, so it doesn't need to take a pointer to the statusbar widget as an
argument.
"clear_tree_and_hex_views()" is purely a display-manipulating routine;
move it to "gtk/proto_draw.c".
Extract from "tree_view_unselect_row_cb()" an "unselect_field()" routine
to do all the work that needs to be done if the currently selected
protocol tree row is unselected, and call it if the currently selected
packet list row is unselected (if it's unselected, there *is* no
protocol tree, so no row can be selected), as well as from
"tree_view_unselect_row_cb()".
Before pushing a new field-description message onto the statusbar, pop
the old one off.
Get rid of an unused variable (set, but not used).
svn path=/trunk/; revision=3513
2001-06-05 07:39:31 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/* Add a placeholder byte view so that there's at least something
|
|
|
|
displayed in the byte view notebook. */
|
|
|
|
add_byte_tab(byte_nb_ptr, "", NULL, NULL, tree_view);
|
Enable "Match Selected" only if there's a field selected *and* we can do
a "Match Selected" on it - we can't do a "Match Selected" if the field
has no value (e.g., FT_NULL) and has a length of 0.
If we unselect the current packet, we don't have a protocol tree, so we
don't have a currently selected field - clear the "Match Selected" menu
item and the display in the status line of information about the
currently selected field.
Move the low-level statusbar manipulation into "gtk/main.c", in routines
whose API doesn't expose anything GTK+-ish.
"close_cap_file()" calls one of those routines to clear out the status
bar, so it doesn't need to take a pointer to the statusbar widget as an
argument.
"clear_tree_and_hex_views()" is purely a display-manipulating routine;
move it to "gtk/proto_draw.c".
Extract from "tree_view_unselect_row_cb()" an "unselect_field()" routine
to do all the work that needs to be done if the currently selected
protocol tree row is unselected, and call it if the currently selected
packet list row is unselected (if it's unselected, there *is* no
protocol tree, so no row can be selected), as well as from
"tree_view_unselect_row_cb()".
Before pushing a new field-description message onto the statusbar, pop
the old one off.
Get rid of an unused variable (set, but not used).
svn path=/trunk/; revision=3513
2001-06-05 07:39:31 +00:00
|
|
|
|
2002-02-18 01:08:44 +00:00
|
|
|
/* Clear the protocol tree by removing all nodes in the ctree.
|
|
|
|
This is how it's done in testgtk.c in GTK+ */
|
2002-11-03 17:38:45 +00:00
|
|
|
#if GTK_MAJOR_VERSION < 2
|
2002-02-18 01:08:44 +00:00
|
|
|
gtk_clist_clear(GTK_CLIST(tree_view));
|
2002-11-03 17:38:45 +00:00
|
|
|
#else
|
|
|
|
gtk_tree_store_clear(GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view))));
|
|
|
|
#endif
|
Enable "Match Selected" only if there's a field selected *and* we can do
a "Match Selected" on it - we can't do a "Match Selected" if the field
has no value (e.g., FT_NULL) and has a length of 0.
If we unselect the current packet, we don't have a protocol tree, so we
don't have a currently selected field - clear the "Match Selected" menu
item and the display in the status line of information about the
currently selected field.
Move the low-level statusbar manipulation into "gtk/main.c", in routines
whose API doesn't expose anything GTK+-ish.
"close_cap_file()" calls one of those routines to clear out the status
bar, so it doesn't need to take a pointer to the statusbar widget as an
argument.
"clear_tree_and_hex_views()" is purely a display-manipulating routine;
move it to "gtk/proto_draw.c".
Extract from "tree_view_unselect_row_cb()" an "unselect_field()" routine
to do all the work that needs to be done if the currently selected
protocol tree row is unselected, and call it if the currently selected
packet list row is unselected (if it's unselected, there *is* no
protocol tree, so no row can be selected), as well as from
"tree_view_unselect_row_cb()".
Before pushing a new field-description message onto the statusbar, pop
the old one off.
Get rid of an unused variable (set, but not used).
svn path=/trunk/; revision=3513
2001-06-05 07:39:31 +00:00
|
|
|
}
|
2003-11-29 06:09:54 +00:00
|
|
|
|