2 * Routines for GTK+ packet display
4 * $Id: proto_draw.c,v 1.3 1999/09/12 20:23:43 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
39 #ifdef NEED_SNPRINTF_H
40 # include "snprintf.h"
47 #include "proto_draw.h"
49 #define BYTE_VIEW_WIDTH 16
50 #define BYTE_VIEW_SEP 8
52 extern GtkWidget *byte_view;
53 extern GdkFont *m_r_font, *m_b_font;
56 proto_tree_draw_node(GNode *node, gpointer data);
59 packet_hex_print(GtkText *bv, guint8 *pd, gint len, gint bstart, gint blen) {
60 gint i = 0, j, k, cur;
61 gchar line[128], hexchars[] = "0123456789abcdef";
62 GdkFont *cur_font, *new_font;
65 /* Print the line number */
66 sprintf(line, "%04x ", i);
67 gtk_text_insert(bv, m_r_font, NULL, NULL, line, -1);
68 /* Do we start in bold? */
69 cur_font = (i >= bstart && i < (bstart + blen)) ? m_b_font : m_r_font;
71 k = i + BYTE_VIEW_WIDTH;
73 /* Print the hex bit */
76 line[cur++] = hexchars[(pd[i] & 0xf0) >> 4];
77 line[cur++] = hexchars[pd[i] & 0x0f];
79 line[cur++] = ' '; line[cur++] = ' ';
83 /* insert a space every BYTE_VIEW_SEP bytes */
84 if( ( i % BYTE_VIEW_SEP ) == 0 ) line[cur++] = ' ';
85 /* Did we cross a bold/plain boundary? */
86 new_font = (i >= bstart && i < (bstart + blen)) ? m_b_font : m_r_font;
87 if (cur_font != new_font) {
88 gtk_text_insert(bv, cur_font, NULL, NULL, line, cur);
94 gtk_text_insert(bv, cur_font, NULL, NULL, line, cur);
97 /* Print the ASCII bit */
98 cur_font = (i >= bstart && i < (bstart + blen)) ? m_b_font : m_r_font;
101 line[cur++] = (isgraph(pd[i])) ? pd[i] : '.';
106 /* insert a space every BYTE_VIEW_SEP bytes */
107 if( ( i % BYTE_VIEW_SEP ) == 0 ) line[cur++] = ' ';
108 /* Did we cross a bold/plain boundary? */
109 new_font = (i >= bstart && i < (bstart + blen)) ? m_b_font : m_r_font;
110 if (cur_font != new_font) {
111 gtk_text_insert(bv, cur_font, NULL, NULL, line, cur);
118 gtk_text_insert(bv, cur_font, NULL, NULL, line, -1);
122 void expand_all_tree(proto_tree *protocol_tree, GtkWidget *tree_view) {
124 for(i=0; i < NUM_TREE_TYPES; i++) {
125 tree_is_expanded[i] = TRUE;
127 gtk_tree_clear_items(GTK_TREE(tree_view), 0, -1);
128 proto_tree_draw(protocol_tree, tree_view);
131 void collapse_all_tree(proto_tree *protocol_tree, GtkWidget *tree_view) {
133 for(i=0; i < NUM_TREE_TYPES; i++) {
134 tree_is_expanded[i] = FALSE;
136 gtk_tree_clear_items(GTK_TREE(tree_view), 0, -1);
137 proto_tree_draw(protocol_tree, tree_view);
141 expand_tree(GtkWidget *w, gpointer data) {
142 gboolean *val = (gint *) data;
147 collapse_tree(GtkWidget *w, gpointer data) {
148 gboolean *val = (gint *) data;
153 set_item_style(GtkWidget *widget, gpointer dummy)
155 gtk_widget_set_style(widget, item_style);
159 proto_tree_draw(proto_tree *protocol_tree, GtkWidget *tree_view)
161 g_node_children_foreach((GNode*) protocol_tree, G_TRAVERSE_ALL,
162 proto_tree_draw_node, tree_view);
166 proto_tree_draw_node(GNode *node, gpointer data)
168 GtkWidget *tree_view = (GtkWidget*) data;
169 field_info *fi = (field_info*) (node->data);
170 GtkWidget *ti, *subtree;
171 gchar label_str[ITEM_LABEL_LENGTH];
177 /* was a free format label produced? */
178 if (fi->representation) {
179 label_ptr = fi->representation;
181 else { /* no, make a generic label */
182 label_ptr = label_str;
183 proto_item_fill_label(fi, label_str);
186 ti = gtk_tree_item_new_with_label(label_ptr);
187 gtk_container_foreach(GTK_CONTAINER(ti), set_item_style, NULL);
188 gtk_object_set_data(GTK_OBJECT(ti), E_TREEINFO_START_KEY, (gpointer) fi->start);
189 gtk_object_set_data(GTK_OBJECT(ti), E_TREEINFO_LEN_KEY, (gpointer) fi->length);
190 gtk_tree_append(GTK_TREE(tree_view), ti);
193 if (g_node_n_children(node) > 0) {
194 subtree = gtk_tree_new();
195 gtk_tree_item_set_subtree(GTK_TREE_ITEM(ti), GTK_WIDGET(subtree));
196 if (tree_is_expanded[fi->tree_type])
197 gtk_tree_item_expand(GTK_TREE_ITEM(ti));
198 gtk_signal_connect(GTK_OBJECT(ti), "expand", (GtkSignalFunc) expand_tree,
199 (gpointer) &tree_is_expanded[fi->tree_type]);
200 gtk_signal_connect(GTK_OBJECT(ti), "collapse", (GtkSignalFunc) collapse_tree,
201 (gpointer) &tree_is_expanded[fi->tree_type]);
203 g_node_children_foreach(node, G_TRAVERSE_ALL,
204 proto_tree_draw_node, subtree);