Redesigned the menu structure of the former statistics stuff,
[obnox/wireshark/wip.git] / gtk / tcp_graph.c
index f9871fd70bafe92dc22f5c483814bcdf067a8942..2f485247b4beb551585b6767bfa8f96bfb74b6f4 100644 (file)
@@ -3,22 +3,22 @@
  * By Pavel Mores <pvl@uh.cz>
  * Win32 port:  rwh@unifiedtech.com
  *
- * $Id: tcp_graph.c,v 1.10 2001/12/12 21:38:59 gerald Exp $
+ * $Id: tcp_graph.c,v 1.52 2004/02/22 18:44:03 ulfl Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998 Gerald Combs
- * 
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
-#include <stdio.h>
 #include <math.h>              /* rint() */
+#include <string.h>
 
-#include <sys/types.h>         /* freebsd requires this */
-
-#ifndef WIN32
-# include <netinet/in.h>       /* ntohs(), IPPROTO_TCP */
-# include <arpa/inet.h>                /* inet_ntoa() */
-#else /* WIN32 */
-# include <stdlib.h>
-#endif /* WIN32 */
+#ifdef NEED_SNPRINTF_H
+# include "snprintf.h"
+#endif
 
+#include "ipproto.h"
 #include "globals.h"           /* cfile */
-#include "packet.h"            /* frame_data */
-#include "prefs_dlg.h"         /* prefs */
-#include "gtkglobals.h"                /* set_scrollbar_placement_srollw() and
-                                * remember_scrolled_window() */
+#include <epan/packet.h>       /* frame_data */
+#include "gtkglobals.h"                /* packet_list */
 #include "simple_dialog.h"
 #include "ui_util.h"
+#include "color.h"
 #include "tcp_graph.h"
+#include "compat_macros.h"
+#include "etypes.h"
+#include "ppptypes.h"
+#include "dlg_utils.h"
+#include <epan/epan_dissect.h>
+#include "tap_menu.h"
 
 /* from <net/ethernet.h> */
 struct ether_header {
@@ -57,15 +58,17 @@ struct ether_header {
        guint8 ether_shost[6];  /* source ether addr */
        guint16 ether_type;     /* packet type ID field */
 };
-#define ETHERTYPE_IP   0x0800
-
 
 /* reverse engineered from capture file, not too difficult :) */
 struct ppp_header {
        guint8 ppp_type;        /* Protocol on PPP connection */
 };
-#define PPPTYPE_IP 0x21
 
+/* 802.1q header */
+struct vlan_802_1_q {
+       guint16 info;
+       guint16 type;
+};
 
 /* from <netinet/ip.h> */
 struct iphdr {
@@ -103,11 +106,11 @@ struct tcphdr {
        guint16 urg_ptr;
 };
 
-#define TCP_SYN(tcphdr)                ( ntohs ((tcphdr).flags) & TH_SYN )
-#define TCP_ACK(tcphdr)                ( ntohs ((tcphdr).flags) & TH_ACK )
+#define TCP_SYN(tcphdr)                ( g_ntohs ((tcphdr).flags) & TH_SYN )
+#define TCP_ACK(tcphdr)                ( g_ntohs ((tcphdr).flags) & TH_ACK )
 #define TCP_DOFF_SHIFT         12
 #define TCP_DOFF_MASK          (0xf << TCP_DOFF_SHIFT)
-#define DOFF(tcphdr)           ( ( ntohs ((tcphdr).flags) & TCP_DOFF_MASK) >> TCP_DOFF_SHIFT )
+#define DOFF(tcphdr)           ( ( g_ntohs ((tcphdr).flags) & TCP_DOFF_MASK) >> TCP_DOFF_SHIFT )
 
 #define TXT_WIDTH      850
 #define TXT_HEIGHT     550
@@ -320,8 +323,13 @@ struct graph {
        int flags;
        GtkWidget *toplevel;    /* keypress handler needs this */
        GtkWidget *drawing_area;
-       GtkWidget *text;                /* text widget for seg list - probably temporary */
+        GtkWidget *text;       /* text widget for seg list - probably
+                                 * temporary */
+#if GTK_MAJOR_VERSION < 2
        GdkFont *font;                  /* font used for annotations etc. */
+#else
+       PangoFontDescription *font;     /* font used for annotations etc. */
+#endif
        GdkGC *fg_gc;
        GdkGC *bg_gc;
        GdkPixmap *title_pixmap;
@@ -385,8 +393,10 @@ int debugging = 0;
 /*int debugging = DBS_TPUT_ELMTS;*/
 
 static void create_gui (struct graph * );
+#if 0
 static void create_text_widget (struct graph * );
 static void display_text (struct graph * );
+#endif
 static void create_drawing_area (struct graph * );
 static void control_panel_create (struct graph * );
 static GtkWidget *control_panel_create_zoom_group (struct graph * );
@@ -448,7 +458,6 @@ static void graph_segment_list_free (struct graph * );
 static void graph_select_segment (struct graph * , int , int );
 static int line_detect_collision (struct element * , int , int );
 static int arc_detect_collision (struct element * , int , int );
-static void update_packet_list (int );
 static void axis_pixmaps_create (struct axis * );
 static void axis_pixmaps_switch (struct axis * );
 static void axis_display (struct axis * );
@@ -502,13 +511,13 @@ static void rtt_put_unack_on_list (struct unack ** , struct unack * );
 static void rtt_delete_unack_from_list (struct unack ** , struct unack * );
 static void rtt_make_elmtlist (struct graph * );
 static void rtt_toggle_seq_origin (struct graph * );
-#ifdef WIN32
+#if defined(WIN32) && !defined(__MINGW32__)
 static int rint (double );     /* compiler template for Windows */
 #endif
 
 static char helptext[] =
 #ifndef WIN32
-"Here's what you can do:\n
+"Here's what you can do:\n\
 - Left Mouse Button selects segment in ethereal's packet list\n\
 - Middle Mouse Button zooms in\n\
 - <shift>-Middle Button zooms out\n\
@@ -516,7 +525,7 @@ static char helptext[] =
 - <ctrl>-Right Mouse Button displays a portion of graph magnified\n\
 - Space toggles crosshairs\n\
 - 's' toggles relative/absolute sequence numbers\n\
-- 't' toggles time origin\n
+- 't' toggles time origin\n\
 ";
 #else /* WIN32 */
 "Here's what you can do:\n\
@@ -532,10 +541,11 @@ static char helptext[] =
 ";
 #endif
 
-void tcp_graph_cb (GtkWidget *w, gpointer data, guint graph_type)
+void tcp_graph_cb (GtkWidget *w _U_, gpointer data, guint callback_action /*graph_type*/ _U_)
 {
        struct segment current;
        struct graph *g;
+    guint graph_type = GPOINTER_TO_INT(data);
 
        debug(DBS_FENTRY) puts ("tcp_graph_cb()");
 
@@ -551,7 +561,7 @@ void tcp_graph_cb (GtkWidget *w, gpointer data, guint graph_type)
                /* currently selected packet is neither TCP over IP over Ethernet II/PPP
                 * nor TCP over IP alone - should display some
                 * kind of warning dialog */
-               simple_dialog(ESD_TYPE_WARN, NULL,
+               simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                    "Selected packet is not a TCP segment");
                return;
        }
@@ -570,37 +580,42 @@ static void create_gui (struct graph *g)
        create_drawing_area(g);
 }
 
+#if 0
 static void create_text_widget (struct graph *g)
 {
        GtkWidget *streamwindow, *txt_scrollw, *box;
 
        debug(DBS_FENTRY) puts ("create_text_widget()");
-       streamwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+       streamwindow = window_new (GTK_WINDOW_TOPLEVEL, "Ethereal: Packet chain");
        gtk_widget_set_name (streamwindow, "Packet chain");
-       gtk_widget_set_usize (GTK_WIDGET (streamwindow), TXT_WIDTH, TXT_HEIGHT);
+       WIDGET_SET_SIZE(streamwindow, TXT_WIDTH, TXT_HEIGHT);
        gtk_container_border_width (GTK_CONTAINER(streamwindow), 2);
-       gtk_signal_connect (GTK_OBJECT (streamwindow), "realize",
-               GTK_SIGNAL_FUNC (window_icon_realize_cb), NULL);
 
        box = gtk_vbox_new (FALSE, 0);
        gtk_container_add (GTK_CONTAINER (streamwindow), box);
        gtk_widget_show (box);
 
-       txt_scrollw = gtk_scrolled_window_new (NULL, NULL);
+       txt_scrollw = scrolled_window_new (NULL, NULL);
+#if GTK_MAJOR_VERSION >= 2
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scrollw), 
+                                   GTK_SHADOW_IN);
+#endif
        gtk_box_pack_start (GTK_BOX (box), txt_scrollw, TRUE, TRUE, 0);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (txt_scrollw),
                                        GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
-       set_scrollbar_placement_scrollw (txt_scrollw, prefs.gui_scrollbar_on_right);
-       remember_scrolled_window (txt_scrollw);
        gtk_widget_show (txt_scrollw);
 
-       g->text = gtk_text_new (NULL, NULL);
-       gtk_text_set_editable (GTK_TEXT (g->text), FALSE);
+#if GTK_MAJOR_VERSION < 2
+       g->text = gtk_text_new(NULL, NULL);
+       gtk_text_set_editable(GTK_TEXT(g->text), FALSE);
+#else
+       g->text = gtk_text_view_new();
+       gtk_text_view_set_editable(GTK_TEXT_VIEW(g->text), FALSE);
+#endif
        gtk_container_add (GTK_CONTAINER (txt_scrollw), g->text);
        gtk_widget_show (g->text);
        gtk_widget_show (streamwindow);
 }
-
 static void display_text (struct graph *g)
 {
        char *line[256];
@@ -608,10 +623,22 @@ static void display_text (struct graph *g)
        double first_time, prev_time;
        unsigned int isn_this=0, isn_opposite=0, seq_this_prev, seq_opposite_prev;
        GdkColor color, *c;
+#if GTK_MAJOR_VERSION >= 2
+        GtkTextBuffer *buf;
+        GtkTextIter    iter;
+#endif
 
        debug(DBS_FENTRY) puts ("display_text()");
-       gdk_color_parse ("SlateGray", &color);
+       if (!gdk_color_parse ("SlateGray", &color)) {
+               /*
+                * XXX - do more than just warn.
+                */
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                   "Could not parse color SlateGray.");
+       }
+#if GTK_MAJOR_VERSION < 2
        gtk_text_freeze (GTK_TEXT (g->text));
+#endif
        snprintf ((char * )line, 256, "%10s%15s%15s%15s%15s%15s%15s%10s\n",
                                        "pkt num", "time", "delta first", "delta prev",
                                        "seqno", "delta first", "delta prev", "data (B)");
@@ -623,13 +650,13 @@ static void display_text (struct graph *g)
        /* we have to find Initial Sequence Number for both ends of connection */
        for (ptr=g->segments; ptr; ptr=ptr->next) {
                if (compare_headers (g->current, ptr, COMPARE_CURR_DIR)) {
-                       isn_this = ntohl (ptr->tcphdr.seq);
+                       isn_this = g_ntohl (ptr->tcphdr.seq);
                        break;
                }
        }
        for (ptr=g->segments; ptr; ptr=ptr->next) {
                if (!compare_headers (g->current, ptr, COMPARE_CURR_DIR)) {
-                       isn_opposite = ntohl (ptr->tcphdr.seq);
+                       isn_opposite = g_ntohl (ptr->tcphdr.seq);
                        break;
                }
        }
@@ -637,7 +664,7 @@ static void display_text (struct graph *g)
        seq_opposite_prev = isn_opposite;
        for (ptr=g->segments; ptr; ptr=ptr->next) {
                double time=ptr->rel_secs + ptr->rel_usecs/1000000.0;
-               unsigned int seq = ntohl (ptr->tcphdr.seq);
+               unsigned int seq = g_ntohl (ptr->tcphdr.seq);
                int seq_delta_isn, seq_delta_prev;
 
                if (compare_headers (g->current, ptr, COMPARE_CURR_DIR)) {
@@ -654,20 +681,26 @@ static void display_text (struct graph *g)
                snprintf ((char *)line, 256, "%10d%15.6f%15.6f%15.6f%15u%15d%15d%10u\n",
                                                ptr->num, time, time-first_time, time-prev_time,
                                                seq, seq_delta_isn, seq_delta_prev,
-                                               ntohs (ptr->iphdr.tot_len) - 4*IHL(&(ptr->iphdr)) -
+                                               g_ntohs (ptr->iphdr.tot_len) - 4*IHL(&(ptr->iphdr)) -
                                                4*DOFF(ptr->tcphdr));
-               gtk_text_insert (GTK_TEXT (g->text), g->font, c, NULL,
-                                               (const char * )line, -1);
+#if GTK_MAJOR_VERSION < 2
+               gtk_text_insert(GTK_TEXT(g->text), g->font, c, NULL,
+                                (const char * )line, -1);
+#else
+                gtk_text_buffer_insert(buf, &iter, (const char *)line, -1);
+#endif
                prev_time = time;
        }
+#if GTK_MAJOR_VERSION < 2
        gtk_text_thaw (GTK_TEXT (g->text));
+#endif
 }
+#endif
 
 static void create_drawing_area (struct graph *g)
 {
        GdkColormap *colormap;
        GdkColor color;
-       GtkWidget *frame, *box;
 #define WINDOW_TITLE_LENGTH 64
        char window_title[WINDOW_TITLE_LENGTH];
 
@@ -678,10 +711,10 @@ static void create_drawing_area (struct graph *g)
        g->font = gdk_font_load ("-biznet-fotinostypewriter-medium-r-normal-*-*-120"
                                                        "-*-*-m-*-iso8859-2");
 #endif
-       g->toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+       snprintf (window_title, WINDOW_TITLE_LENGTH, "TCP Graph %d - Ethereal",
+                                       refnum);
+       g->toplevel = window_new (GTK_WINDOW_TOPLEVEL, window_title);
        gtk_widget_set_name (g->toplevel, "Test Graph");
-       gtk_signal_connect (GTK_OBJECT (g->toplevel), "realize",
-               GTK_SIGNAL_FUNC (window_icon_realize_cb), NULL);
 
        /* Create the drawing area */
        g->drawing_area = gtk_drawing_area_new ();
@@ -691,39 +724,38 @@ static void create_drawing_area (struct graph *g)
                                        g->wp.height + g->wp.y + g->x_axis->s.height);
        gtk_widget_show (g->drawing_area);
 
-       gtk_signal_connect (GTK_OBJECT (g->drawing_area), "expose_event",
-                                                       (GtkSignalFunc )expose_event, NULL);
+       SIGNAL_CONNECT(g->drawing_area, "expose_event", expose_event, NULL);
        /* this has to be done later, after the widget has been shown */
        /*
-       gtk_signal_connect (GTK_OBJECT(g->drawing_area),"configure_event",
-                                                       (GtkSignalFunc )configure_event, NULL);
+       SIGNAL_CONNECT(g->drawing_area,"configure_event", configure_event,
+        NULL);
         */
-       gtk_signal_connect (GTK_OBJECT (g->drawing_area), "motion_notify_event",
-                       (GtkSignalFunc )motion_notify_event, NULL);
-       gtk_signal_connect (GTK_OBJECT (g->drawing_area), "button_press_event",
-                       (GtkSignalFunc )button_press_event, NULL);
-       gtk_signal_connect (GTK_OBJECT (g->drawing_area), "button_release_event",
-                       (GtkSignalFunc )button_release_event, NULL);
-       gtk_signal_connect (GTK_OBJECT (g->drawing_area), "leave_notify_event",
-                       (GtkSignalFunc )leave_notify_event, NULL);
-       gtk_signal_connect (GTK_OBJECT (g->drawing_area), "enter_notify_event",
-                       (GtkSignalFunc )enter_notify_event, NULL);
-       gtk_signal_connect (GTK_OBJECT (g->toplevel), "destroy",
-                       (GtkSignalFunc )callback_toplevel_destroy, g);
+       SIGNAL_CONNECT(g->drawing_area, "motion_notify_event",
+                       motion_notify_event, NULL);
+       SIGNAL_CONNECT(g->drawing_area, "button_press_event",
+                       button_press_event, NULL);
+       SIGNAL_CONNECT(g->drawing_area, "button_release_event",
+                       button_release_event, NULL);
+       SIGNAL_CONNECT(g->drawing_area, "leave_notify_event",
+                       leave_notify_event, NULL);
+       SIGNAL_CONNECT(g->drawing_area, "enter_notify_event",
+                       enter_notify_event, NULL);
+       SIGNAL_CONNECT(g->toplevel, "destroy", callback_toplevel_destroy, g);
        /* why doesn't drawing area send key_press_signals? */
-       gtk_signal_connect (GTK_OBJECT (g->toplevel), "key_press_event",
-                       (GtkSignalFunc )key_press_event, NULL);
-       gtk_signal_connect (GTK_OBJECT (g->toplevel), "key_release_event",
-                       (GtkSignalFunc )key_release_event, NULL);
-       gtk_widget_set_events (g->toplevel,GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK);
-
-       gtk_widget_set_events (g->drawing_area, GDK_EXPOSURE_MASK
-                                                                       | GDK_LEAVE_NOTIFY_MASK
-                                                                       | GDK_ENTER_NOTIFY_MASK
-                                                                       | GDK_BUTTON_PRESS_MASK
-                                                                       | GDK_BUTTON_RELEASE_MASK
-                                                                       | GDK_POINTER_MOTION_MASK
-                                                                       | GDK_POINTER_MOTION_HINT_MASK);
+       SIGNAL_CONNECT(g->toplevel, "key_press_event", key_press_event, NULL);
+       SIGNAL_CONNECT(g->toplevel, "key_release_event", key_release_event,
+                       NULL);
+       gtk_widget_set_events(g->toplevel,
+                              GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK);
+
+       gtk_widget_set_events (g->drawing_area,
+                               GDK_EXPOSURE_MASK
+                               | GDK_LEAVE_NOTIFY_MASK
+                               | GDK_ENTER_NOTIFY_MASK
+                               | GDK_BUTTON_PRESS_MASK
+                               | GDK_BUTTON_RELEASE_MASK
+                               | GDK_POINTER_MOTION_MASK
+                               | GDK_POINTER_MOTION_HINT_MASK);
 
 #if 0
        frame = gtk_frame_new (NULL);
@@ -741,9 +773,6 @@ static void create_drawing_area (struct graph *g)
 
        gtk_container_add (GTK_CONTAINER (g->toplevel), g->drawing_area);
        gtk_widget_show (g->toplevel);
-       snprintf (window_title, WINDOW_TITLE_LENGTH, "TCP Graph %d - Ethereal",
-                                       refnum);
-       gtk_window_set_title (GTK_WINDOW (g->toplevel), window_title);
 
        /* in case we didn't get what we asked for */
        g->wp.width = GTK_WIDGET (g->drawing_area)->allocation.width -
@@ -751,21 +780,49 @@ static void create_drawing_area (struct graph *g)
        g->wp.height = GTK_WIDGET (g->drawing_area)->allocation.height -
                                                g->wp.y - g->x_axis->s.height;
 
+#if GTK_MAJOR_VERSION < 2
        g->font = g->drawing_area->style->font;
        gdk_font_ref (g->font);
+#else
+        g->font = g->drawing_area->style->font_desc;
+#endif
 
        colormap = gdk_window_get_colormap (g->drawing_area->window);
        if (!xor_gc) {
                xor_gc = gdk_gc_new (g->drawing_area->window);
                gdk_gc_set_function (xor_gc, GDK_XOR);
-               gdk_color_parse ("gray15", &color);
-               gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE);
+               if (!gdk_color_parse ("gray15", &color)) {
+                       /*
+                        * XXX - do more than just warn.
+                        */
+                       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                           "Could not parse color gray15.");
+               }
+               if (!gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE)) {
+                       /*
+                        * XXX - do more than just warn.
+                        */
+                       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                           "Could not allocate color gray15.");
+               }
                gdk_gc_set_foreground (xor_gc, &color);
        }
        g->fg_gc = gdk_gc_new (g->drawing_area->window);
        g->bg_gc = gdk_gc_new (g->drawing_area->window);
-       gdk_color_parse ("white", &color);
-       gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE);
+       if (!gdk_color_parse ("white", &color)) {
+               /*
+                * XXX - do more than just warn.
+                */
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                   "Could not parse color white.");
+       }
+       if (!gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE)) {
+               /*
+                * XXX - do more than just warn.
+                */
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                   "Could not allocate color white.");
+       }
        gdk_gc_set_foreground (g->bg_gc, &color);
 
        /* this is probably quite an ugly way to get rid of the first configure
@@ -778,16 +835,16 @@ static void create_drawing_area (struct graph *g)
         * and we don't have the GC's at all. so we just postpone installation
         * of configure handler until we're ready to deal with it.
         *
-        * !!! NEMÌLO BY TO BÝT NA KONCI graph_init_sequence()? !!! 
+        * !!! NEMÌLO BY TO BÝT NA KONCI graph_init_sequence()? !!!
         *
         */
-       gtk_signal_connect (GTK_OBJECT(g->drawing_area),"configure_event",
-                                                       (GtkSignalFunc )configure_event, NULL);
+       SIGNAL_CONNECT(g->drawing_area,"configure_event", configure_event,
+                       NULL);
 
        /* puts ("exiting create_drawing_area()"); */
 }
 
-static void callback_toplevel_destroy (GtkWidget *widget, gpointer data)
+static void callback_toplevel_destroy (GtkWidget *widget _U_, gpointer data)
 {
        struct graph *g = (struct graph * )data;
 
@@ -801,7 +858,7 @@ static void control_panel_create (struct graph *g)
 {
        GtkWidget *toplevel, *notebook;
        GtkWidget *table;
-       GtkWidget *help, *close, *button_box;
+       GtkWidget *help_bt, *close_bt, *bbox;
 #define WINDOW_TITLE_LENGTH 64
        char window_title[WINDOW_TITLE_LENGTH];
 
@@ -814,36 +871,33 @@ static void control_panel_create (struct graph *g)
        control_panel_add_cross_page (g, notebook);
        control_panel_add_graph_type_page (g, notebook);
 
-       /* bottom buttons group */
-       help = gtk_button_new_with_label ("Help");
-       close = gtk_button_new_with_label ("Close");
-       button_box = gtk_hbox_new (TRUE, 0);
-       gtk_box_pack_start (GTK_BOX (button_box), help, TRUE, TRUE, 0);
-       gtk_box_pack_start (GTK_BOX (button_box), close, TRUE, TRUE, 0);
-
-       toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-       gtk_signal_connect (GTK_OBJECT (toplevel), "realize",
-               GTK_SIGNAL_FUNC (window_icon_realize_cb), NULL);
+       snprintf (window_title, WINDOW_TITLE_LENGTH,
+                               "Graph %d - Control - Ethereal", refnum);
+       toplevel = window_new (GTK_WINDOW_TOPLEVEL, window_title);
+       SIGNAL_CONNECT(toplevel, "destroy", callback_toplevel_destroy, g);
 
        table = gtk_table_new (2, 1,  FALSE);
        gtk_container_add (GTK_CONTAINER (toplevel), table);
 
        gtk_table_attach (GTK_TABLE (table), notebook, 0, 1, 0, 1,
-                                               GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
-       gtk_table_attach (GTK_TABLE (table), button_box, 0, 1, 1, 2,
-                                               GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
+                          GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
 
-       gtk_signal_connect (GTK_OBJECT (close), "clicked",
-                       (GtkSignalFunc )callback_close, g);
-       gtk_signal_connect (GTK_OBJECT (help), "clicked",
-                       (GtkSignalFunc )callback_create_help, g);
+       /* bottom buttons */
+       bbox = dlg_button_row_new(GTK_STOCK_HELP, GTK_STOCK_CLOSE, NULL);
+       gtk_table_attach (GTK_TABLE (table), bbox, 0, 1, 1, 2,
+                          GTK_FILL|GTK_EXPAND, GTK_FILL, 5, 5);
+       gtk_widget_show(bbox);
+
+       help_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_HELP);
+       SIGNAL_CONNECT(help_bt, "clicked", callback_create_help, g);
+
+       close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
+       gtk_widget_grab_default(close_bt);
+       SIGNAL_CONNECT(close_bt, "clicked", callback_close, g);
 
        /* gtk_widget_show_all (table); */
        /* g->gui.control_panel = table; */
        gtk_widget_show_all (toplevel);
-       snprintf (window_title, WINDOW_TITLE_LENGTH,
-                               "Graph %d - Control - Ethereal", refnum);
-       gtk_window_set_title (GTK_WINDOW (toplevel), window_title);
        g->gui.control_panel = toplevel;
 }
 
@@ -912,10 +966,8 @@ static void control_panel_add_origin_page (struct graph *g, GtkWidget *n)
        g->gui.time_orig_conn = (GtkToggleButton * )time_orig_conn;
        g->gui.seq_orig_isn = (GtkToggleButton * )seq_orig_isn;
 
-       gtk_signal_connect (GTK_OBJECT (time_orig_conn), "toggled",
-                       (GtkSignalFunc )callback_time_origin, g);
-       gtk_signal_connect (GTK_OBJECT (seq_orig_isn), "toggled",
-                       (GtkSignalFunc )callback_seq_origin, g);
+       SIGNAL_CONNECT(time_orig_conn, "toggled", callback_time_origin, g);
+       SIGNAL_CONNECT(seq_orig_isn, "toggled", callback_seq_origin, g);
 
        box = gtk_vbox_new (FALSE, 0);
        gtk_container_set_border_width (GTK_CONTAINER (box), 5);
@@ -946,7 +998,7 @@ static void control_panel_add_graph_type_page (struct graph *g, GtkWidget *n)
        gtk_notebook_append_page (GTK_NOTEBOOK (n), frame, label);
 }
 
-static void callback_close (GtkWidget *widget, gpointer data)
+static void callback_close (GtkWidget *widget _U_, gpointer data)
 {
        struct graph *g = (struct graph * )data;
 
@@ -956,48 +1008,62 @@ static void callback_close (GtkWidget *widget, gpointer data)
        }
 }
 
-static void callback_create_help (GtkWidget *widget, gpointer data)
+static void callback_create_help(GtkWidget *widget _U_, gpointer data _U_)
 {
+       GtkWidget *toplevel, *box, *text, *scroll, *bbox, *close_bt;
+#if GTK_MAJOR_VERSION < 2
        struct graph *g = (struct graph * )data;
-       GtkWidget *toplevel, *box, *text, *scroll, *close;
+#else
+        GtkTextBuffer *buf;
+#endif
 
-       toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-       gtk_window_set_title(GTK_WINDOW(toplevel), "Help for TCP graphing");
-       gtk_widget_set_usize (toplevel, 500, 400);
-       gtk_signal_connect (GTK_OBJECT (toplevel), "realize",
-               GTK_SIGNAL_FUNC (window_icon_realize_cb), NULL);
+       toplevel = window_new (GTK_WINDOW_TOPLEVEL, "Help for TCP graphing");
+       WIDGET_SET_SIZE(toplevel, 500, 400);
 
        box = gtk_vbox_new (FALSE, 0);
        gtk_container_add (GTK_CONTAINER (toplevel), box);
-       scroll = gtk_scrolled_window_new (NULL, NULL);
-       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
-                                               GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+       scroll = scrolled_window_new (NULL, NULL);
+#if GTK_MAJOR_VERSION >= 2
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), 
+                                   GTK_SHADOW_IN);
+#endif
        gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);
+#if GTK_MAJOR_VERSION < 2
        text = gtk_text_new (NULL, NULL);
        gtk_text_set_editable (GTK_TEXT (text), FALSE);
        gtk_text_set_line_wrap (GTK_TEXT (text), FALSE);
        gtk_text_set_word_wrap (GTK_TEXT (text), FALSE);
        gtk_text_insert (GTK_TEXT (text), g->font, NULL, NULL, helptext, -1);
+#else
+        text = gtk_text_view_new();
+       gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
+        buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
+       gtk_text_buffer_set_text(buf, helptext, -1);
+#endif
        gtk_container_add (GTK_CONTAINER (scroll), text);
-       close = gtk_button_new_with_label ("Close");
-       gtk_box_pack_start (GTK_BOX (box), close, FALSE, FALSE, 0);
-       gtk_signal_connect (GTK_OBJECT (close), "clicked",
-                       (GtkSignalFunc )callback_close_help, toplevel);
-       
+
+    bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
+       gtk_box_pack_start (GTK_BOX (box), bbox, FALSE, FALSE, 0);
+    gtk_widget_show(bbox);
+
+    close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
+       SIGNAL_CONNECT(close_bt, "clicked", callback_close_help, toplevel);
+    gtk_widget_grab_default(close_bt);
+
        gtk_widget_show_all (toplevel);
 }
 
-static void callback_close_help (GtkWidget *widget, gpointer data)
+static void callback_close_help (GtkWidget *widget _U_, gpointer data)
 {
        gtk_widget_destroy ((GtkWidget * )data);
 }
 
-static void callback_time_origin (GtkWidget *toggle, gpointer data)
+static void callback_time_origin (GtkWidget *toggle _U_, gpointer data)
 {
        toggle_time_origin ((struct graph * )data);
 }
 
-static void callback_seq_origin (GtkWidget *toggle, gpointer data)
+static void callback_seq_origin (GtkWidget *toggle _U_, gpointer data)
 {
        toggle_seq_origin ((struct graph * )data);
 }
@@ -1048,12 +1114,12 @@ static GtkWidget *control_panel_create_zoom_group (struct graph *g)
 
        zoom_separator2 = gtk_hseparator_new ();
 
-       zoom_h_adj = (GtkAdjustment * )gtk_adjustment_new (1.2, 1.0, 5, 0.1, 1, 0);
+       zoom_h_adj = (GtkAdjustment * )gtk_adjustment_new ((gfloat)1.2, 1.0, 5, (gfloat)0.1, 1, 0);
        zoom_h_step = gtk_spin_button_new (zoom_h_adj, 0, 1);
        gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (zoom_h_step), TRUE);
        zoom_h_step_label = gtk_label_new ("Horizontal step:");
 
-       zoom_v_adj = (GtkAdjustment * )gtk_adjustment_new (1.2, 1.0, 5, 0.1, 1, 0);
+       zoom_v_adj = (GtkAdjustment * )gtk_adjustment_new ((gfloat)1.2, 1.0, 5, (gfloat)0.1, 1, 0);
        zoom_v_step = gtk_spin_button_new (zoom_v_adj, 0, 1);
        gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (zoom_v_step), TRUE);
        zoom_v_step_label = gtk_label_new ("Vertical step:");
@@ -1061,16 +1127,13 @@ static GtkWidget *control_panel_create_zoom_group (struct graph *g)
        g->zoom.widget.h_step = (GtkSpinButton * )zoom_h_step;
        g->zoom.widget.v_step = (GtkSpinButton * )zoom_v_step;
 
-       zoom_same_toggle = gtk_check_button_new_with_label ("Keep them the same");
+       zoom_same_toggle = gtk_check_button_new_with_label("Keep them the same");
        zoom_ratio_toggle = gtk_check_button_new_with_label("Preserve their ratio");
-       gtk_object_set_data (GTK_OBJECT (zoom_same_toggle), "flag",
-                                               (gpointer )ZOOM_STEPS_SAME);
-       gtk_object_set_data (GTK_OBJECT (zoom_ratio_toggle), "flag",
-                                               (gpointer )ZOOM_STEPS_KEEP_RATIO);
-       gtk_signal_connect (GTK_OBJECT (zoom_same_toggle), "clicked",
-                               (GtkSignalFunc )callback_zoom_flags, g);
-       gtk_signal_connect (GTK_OBJECT (zoom_ratio_toggle), "clicked",
-                               (GtkSignalFunc )callback_zoom_flags, g);
+       OBJECT_SET_DATA(zoom_same_toggle, "flag", (gpointer)ZOOM_STEPS_SAME);
+       OBJECT_SET_DATA(zoom_ratio_toggle, "flag",
+                        (gpointer)ZOOM_STEPS_KEEP_RATIO);
+       SIGNAL_CONNECT(zoom_same_toggle, "clicked", callback_zoom_flags, g);
+       SIGNAL_CONNECT(zoom_ratio_toggle, "clicked", callback_zoom_flags, g);
 
        zoom_step_table = gtk_table_new (4, 2,  FALSE);
        gtk_table_attach (GTK_TABLE (zoom_step_table), zoom_h_step_label, 0,1,0,1,
@@ -1095,15 +1158,12 @@ static GtkWidget *control_panel_create_zoom_group (struct graph *g)
        zoom_frame = gtk_frame_new ("Zoom");
        gtk_container_add (GTK_CONTAINER (zoom_frame), zoom_box);
 
-       gtk_object_set_data (GTK_OBJECT (zoom_h_step), "direction", (gpointer )0);
-       gtk_object_set_data (GTK_OBJECT (zoom_v_step), "direction", (gpointer )1);
+       OBJECT_SET_DATA(zoom_h_step, "direction", GINT_TO_POINTER(0));
+       OBJECT_SET_DATA(zoom_v_step, "direction", GINT_TO_POINTER(1));
 
-       gtk_signal_connect (GTK_OBJECT (zoom_in), "toggled",
-                               (GtkSignalFunc )callback_zoom_inout, g);
-       gtk_signal_connect (GTK_OBJECT (zoom_h_step), "changed",
-                               (GtkSignalFunc )callback_zoom_step, g);
-       gtk_signal_connect (GTK_OBJECT (zoom_v_step), "changed",
-                               (GtkSignalFunc )callback_zoom_step, g);
+       SIGNAL_CONNECT(zoom_in, "toggled", callback_zoom_inout, g);
+       SIGNAL_CONNECT(zoom_h_step, "changed", callback_zoom_step, g);
+        SIGNAL_CONNECT(zoom_v_step, "changed", callback_zoom_step, g);
 
        g->zoom.widget.in_toggle = (GtkToggleButton * )zoom_in;
        g->zoom.widget.out_toggle = (GtkToggleButton * )zoom_out;
@@ -1123,13 +1183,13 @@ static void callback_zoom_inout (GtkWidget *toggle, gpointer data)
 static void callback_zoom_step (GtkWidget *spin, gpointer data)
 {
        struct graph *g = (struct graph * )data;
-       float value;
+       double value;
        int direction;
        double *zoom_this, *zoom_other;
        GtkSpinButton *widget_this, *widget_other;
        double old_this;
 
-       direction = (int )gtk_object_get_data (GTK_OBJECT (spin), "direction");
+       direction = (int)OBJECT_GET_DATA(spin, "direction");
        value = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (spin));
 
        if (direction) {
@@ -1148,32 +1208,32 @@ static void callback_zoom_step (GtkWidget *spin, gpointer data)
        *zoom_this = value;
        if (g->zoom.flags & ZOOM_STEPS_SAME) {
                *zoom_other = value;
-               gtk_spin_button_set_value (widget_other, *zoom_other);
+               gtk_spin_button_set_value (widget_other, (gfloat) *zoom_other);
        } else if (g->zoom.flags & ZOOM_STEPS_KEEP_RATIO) {
                double old_other = *zoom_other;
                *zoom_other *= value / old_this;
                if (*zoom_other < 1.0) {
                        *zoom_other = 1.0;
                        *zoom_this = old_this * 1.0 / old_other;
-                       gtk_spin_button_set_value (widget_this, *zoom_this);
+                       gtk_spin_button_set_value (widget_this, (gfloat) *zoom_this);
                } else if (*zoom_other > 5.0) {
                        *zoom_other = 5.0;
                        *zoom_this = old_this * 5.0 / old_other;
-                       gtk_spin_button_set_value (widget_this, *zoom_this);
+                       gtk_spin_button_set_value (widget_this, (gfloat) *zoom_this);
                }
-               gtk_spin_button_set_value (widget_other, *zoom_other);
+               gtk_spin_button_set_value (widget_other, (gfloat) *zoom_other);
        }
 }
 
 static void callback_zoom_flags (GtkWidget *toggle, gpointer data)
 {
        struct graph *g = (struct graph * )data;
-       int flag = (int )gtk_object_get_data (GTK_OBJECT (toggle), "flag");
+       int flag = (int)OBJECT_GET_DATA(toggle, "flag");
 
        if (GTK_TOGGLE_BUTTON (toggle)->active)
-               g->zoom.flags |= flag;  
+               g->zoom.flags |= flag;
        else
-               g->zoom.flags &= ~flag; 
+               g->zoom.flags &= ~flag;
 }
 
 static void update_zoom_spins (struct graph *g)
@@ -1235,11 +1295,11 @@ static GtkWidget *control_panel_create_magnify_group (struct graph *g)
                                GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 5, 0);
 
        mag_h_zoom_label = gtk_label_new ("Horizontal:");
-       mag_h_zoom_adj = (GtkAdjustment *)gtk_adjustment_new(10.0,1.0,25.0,0.1,1,0);
+       mag_h_zoom_adj = (GtkAdjustment *)gtk_adjustment_new(10.0, 1.0, 25.0, (gfloat)0.1, 1, 0);
        mag_h_zoom = gtk_spin_button_new (mag_h_zoom_adj, 0, 1);
 
        mag_v_zoom_label = gtk_label_new ("Vertical:");
-       mag_v_zoom_adj = (GtkAdjustment *)gtk_adjustment_new(10.0,1.0,25.0,0.1,1,0);
+       mag_v_zoom_adj = (GtkAdjustment *)gtk_adjustment_new(10.0, 1.0, 25.0, (gfloat)0.1, 1, 0);
        mag_v_zoom = gtk_spin_button_new (mag_v_zoom_adj, 0, 1);
 
        mag_zoom_same = gtk_check_button_new_with_label ("Keep them the same");
@@ -1271,29 +1331,19 @@ static GtkWidget *control_panel_create_magnify_group (struct graph *g)
 
        g->magnify.widget.h_zoom = (GtkSpinButton * )mag_h_zoom;
        g->magnify.widget.v_zoom = (GtkSpinButton * )mag_v_zoom;
-       gtk_object_set_data (GTK_OBJECT (mag_h_zoom), "direction", (gpointer )0);
-       gtk_object_set_data (GTK_OBJECT (mag_v_zoom), "direction", (gpointer )1);
-       gtk_object_set_data (GTK_OBJECT (mag_zoom_same), "flag",
-                                                                               (gpointer )MAGZOOMS_SAME);
-       gtk_object_set_data (GTK_OBJECT (mag_zoom_ratio), "flag",
-                                                                               (gpointer )MAGZOOMS_SAME_RATIO);
-
-       gtk_signal_connect (GTK_OBJECT (mag_width), "changed",
-                               (GtkSignalFunc )callback_mag_width, g);
-       gtk_signal_connect (GTK_OBJECT (mag_height), "changed",
-                               (GtkSignalFunc )callback_mag_height, g);
-       gtk_signal_connect (GTK_OBJECT (mag_x), "changed",
-                               (GtkSignalFunc )callback_mag_x, g);
-       gtk_signal_connect (GTK_OBJECT (mag_y), "changed",
-                               (GtkSignalFunc )callback_mag_y, g);
-       gtk_signal_connect (GTK_OBJECT (mag_h_zoom), "changed",
-                               (GtkSignalFunc )callback_mag_zoom, g);
-       gtk_signal_connect (GTK_OBJECT (mag_v_zoom), "changed",
-                               (GtkSignalFunc )callback_mag_zoom, g);
-       gtk_signal_connect (GTK_OBJECT (mag_zoom_same), "clicked",
-                               (GtkSignalFunc )callback_mag_flags, g);
-       gtk_signal_connect (GTK_OBJECT (mag_zoom_ratio), "clicked",
-                               (GtkSignalFunc )callback_mag_flags, g);
+       OBJECT_SET_DATA(mag_h_zoom, "direction", GINT_TO_POINTER(0));
+       OBJECT_SET_DATA(mag_v_zoom, "direction", GINT_TO_POINTER(1));
+       OBJECT_SET_DATA(mag_zoom_same, "flag", (gpointer)MAGZOOMS_SAME);
+       OBJECT_SET_DATA(mag_zoom_ratio, "flag", (gpointer)MAGZOOMS_SAME_RATIO);
+
+       SIGNAL_CONNECT(mag_width, "changed", callback_mag_width, g);
+       SIGNAL_CONNECT(mag_height, "changed", callback_mag_height, g);
+       SIGNAL_CONNECT(mag_x, "changed", callback_mag_x, g);
+       SIGNAL_CONNECT(mag_y, "changed", callback_mag_y, g);
+       SIGNAL_CONNECT(mag_h_zoom, "changed", callback_mag_zoom, g);
+       SIGNAL_CONNECT(mag_v_zoom, "changed", callback_mag_zoom, g);
+       SIGNAL_CONNECT(mag_zoom_same, "clicked", callback_mag_flags, g);
+       SIGNAL_CONNECT(mag_zoom_ratio, "clicked", callback_mag_flags, g);
 
        return mag_frame;
 }
@@ -1329,7 +1379,7 @@ static void callback_mag_y (GtkWidget *spin, gpointer data)
 static void callback_mag_zoom (GtkWidget *spin, gpointer data)
 {
        struct graph *g = (struct graph * )data;
-       float value;
+       double value;
        int direction;
        double *zoom_this, *zoom_other;
        GtkSpinButton *widget_this, *widget_other;
@@ -1340,7 +1390,7 @@ static void callback_mag_zoom (GtkWidget *spin, gpointer data)
                g->magnify.flags &= ~MAGZOOMS_IGNORE;
                return;
        }
-       direction = (int )gtk_object_get_data (GTK_OBJECT (spin), "direction");
+       direction = (int)OBJECT_GET_DATA(spin, "direction");
        value = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (spin));
 
        if (direction) {
@@ -1360,7 +1410,7 @@ static void callback_mag_zoom (GtkWidget *spin, gpointer data)
        if (g->magnify.flags & MAGZOOMS_SAME) {
                *zoom_other = value;
                /* g->magnify.flags |= MAGZOOMS_IGNORE; */
-               gtk_spin_button_set_value (widget_other, *zoom_other);
+               gtk_spin_button_set_value (widget_other, (gfloat) *zoom_other);
        } else if (g->magnify.flags & MAGZOOMS_SAME_RATIO) {
                double old_other = *zoom_other;
                *zoom_other *= value / old_this;
@@ -1368,27 +1418,27 @@ static void callback_mag_zoom (GtkWidget *spin, gpointer data)
                        *zoom_other = 1.0;
                        *zoom_this = old_this * 1.0 / old_other;
                        /* g->magnify.flags |= MAGZOOMS_IGNORE; */
-                       gtk_spin_button_set_value (widget_this, *zoom_this);
+                       gtk_spin_button_set_value (widget_this, (gfloat) *zoom_this);
                } else if (*zoom_other > 25.0) {
                        *zoom_other = 25.0;
                        *zoom_this = old_this * 25.0 / old_other;
                        /* g->magnify.flags |= MAGZOOMS_IGNORE; */
-                       gtk_spin_button_set_value (widget_this, *zoom_this);
+                       gtk_spin_button_set_value (widget_this, (gfloat) *zoom_this);
                }
                /* g->magnify.flags |= MAGZOOMS_IGNORE; */
-               gtk_spin_button_set_value (widget_other, *zoom_other);
+               gtk_spin_button_set_value (widget_other, (gfloat) *zoom_other);
        }
 }
 
 static void callback_mag_flags (GtkWidget *toggle, gpointer data)
 {
        struct graph *g = (struct graph * )data;
-       int flag = (int )gtk_object_get_data (GTK_OBJECT (toggle), "flag");
+       int flag = (int)OBJECT_GET_DATA(toggle, "flag");
 
        if (GTK_TOGGLE_BUTTON (toggle)->active)
-               g->magnify.flags |= flag;       
+               g->magnify.flags |= flag;
        else
-               g->magnify.flags &= ~flag;      
+               g->magnify.flags &= ~flag;
 }
 
 static GtkWidget *control_panel_create_zoomlock_group (struct graph *g)
@@ -1405,16 +1455,15 @@ static GtkWidget *control_panel_create_zoomlock_group (struct graph *g)
                                        "vertical");
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (zoom_lock_none), TRUE);
        zoom_lock_box = gtk_hbox_new (FALSE, 0);
-       gtk_box_pack_start (GTK_BOX (zoom_lock_box), zoom_lock_none, TRUE, TRUE, 0);
-       gtk_box_pack_start (GTK_BOX (zoom_lock_box), zoom_lock_h, TRUE, TRUE, 0);
-       gtk_box_pack_start (GTK_BOX (zoom_lock_box), zoom_lock_v, TRUE, TRUE, 0);
+       gtk_box_pack_start(GTK_BOX(zoom_lock_box), zoom_lock_none,
+                           TRUE, TRUE, 0);
+       gtk_box_pack_start(GTK_BOX(zoom_lock_box), zoom_lock_h, TRUE, TRUE, 0);
+       gtk_box_pack_start(GTK_BOX(zoom_lock_box), zoom_lock_v, TRUE, TRUE, 0);
        zoom_lock_frame = gtk_frame_new ("Zoom lock:");
        gtk_container_add (GTK_CONTAINER (zoom_lock_frame), zoom_lock_box);
 
-       gtk_signal_connect (GTK_OBJECT (zoom_lock_h), "toggled",
-                       (GtkSignalFunc )callback_zoomlock_h, g);
-       gtk_signal_connect (GTK_OBJECT (zoom_lock_v), "toggled",
-                       (GtkSignalFunc )callback_zoomlock_v, g);
+       SIGNAL_CONNECT(zoom_lock_h, "toggled", callback_zoomlock_h, g);
+       SIGNAL_CONNECT(zoom_lock_v, "toggled", callback_zoomlock_v, g);
 
        return zoom_lock_frame;
 }
@@ -1424,9 +1473,9 @@ static void callback_zoomlock_h (GtkWidget *toggle, gpointer data)
        struct graph *g = (struct graph * )data;
 
        if (GTK_TOGGLE_BUTTON (toggle)->active)
-               g->zoom.flags |= ZOOM_HLOCK;    
+               g->zoom.flags |= ZOOM_HLOCK;
        else
-               g->zoom.flags &= ~ZOOM_HLOCK;   
+               g->zoom.flags &= ~ZOOM_HLOCK;
 }
 
 static void callback_zoomlock_v (GtkWidget *toggle, gpointer data)
@@ -1434,9 +1483,9 @@ static void callback_zoomlock_v (GtkWidget *toggle, gpointer data)
        struct graph *g = (struct graph * )data;
 
        if (GTK_TOGGLE_BUTTON (toggle)->active)
-               g->zoom.flags |= ZOOM_VLOCK;    
+               g->zoom.flags |= ZOOM_VLOCK;
        else
-               g->zoom.flags &= ~ZOOM_VLOCK;   
+               g->zoom.flags &= ~ZOOM_VLOCK;
 }
 
 static GtkWidget *control_panel_create_cross_group (struct graph *g)
@@ -1458,8 +1507,7 @@ static GtkWidget *control_panel_create_cross_group (struct graph *g)
        frame = gtk_frame_new (NULL);
        gtk_container_add (GTK_CONTAINER (frame), vbox);
 
-       gtk_signal_connect (GTK_OBJECT (on), "toggled",
-                               (GtkSignalFunc )callback_cross_on_off, g);
+       SIGNAL_CONNECT(on, "toggled", callback_cross_on_off, g);
 
        g->cross.on_toggle = (GtkToggleButton * )on;
        g->cross.off_toggle = (GtkToggleButton * )off;
@@ -1524,25 +1572,18 @@ static GtkWidget *control_panel_create_graph_type_group (struct graph *g)
        graph_frame = gtk_frame_new ("Graph type:");
        gtk_container_add (GTK_CONTAINER (graph_frame), graph_box);
 
-       gtk_object_set_data (GTK_OBJECT (graph_tseqstevens), "new-graph-type",
-                                                       (gpointer )0);
-       gtk_object_set_data (GTK_OBJECT (graph_tseqttrace), "new-graph-type",
-                                                       (gpointer )1);
-       gtk_object_set_data (GTK_OBJECT (graph_tput), "new-graph-type", 
-                                                       (gpointer )2);
-       gtk_object_set_data (GTK_OBJECT (graph_rtt), "new-graph-type", 
-                                                       (gpointer )3);
-
-       gtk_signal_connect (GTK_OBJECT (graph_tseqttrace), "toggled",
-                               (GtkSignalFunc )callback_graph_type, g);
-       gtk_signal_connect (GTK_OBJECT (graph_tseqstevens), "toggled",
-                               (GtkSignalFunc )callback_graph_type, g);
-       gtk_signal_connect (GTK_OBJECT (graph_tput), "toggled",
-                               (GtkSignalFunc )callback_graph_type, g);
-       gtk_signal_connect (GTK_OBJECT (graph_rtt), "toggled",
-                               (GtkSignalFunc )callback_graph_type, g);
-       gtk_signal_connect (GTK_OBJECT (graph_init), "toggled",
-                               (GtkSignalFunc )callback_graph_init_on_typechg, g);
+       OBJECT_SET_DATA(graph_tseqstevens, "new-graph-type",
+                        GINT_TO_POINTER(0));
+       OBJECT_SET_DATA(graph_tseqttrace, "new-graph-type", GINT_TO_POINTER(1));
+       OBJECT_SET_DATA(graph_tput, "new-graph-type", GINT_TO_POINTER(2));
+       OBJECT_SET_DATA(graph_rtt, "new-graph-type", GINT_TO_POINTER(3));
+
+        SIGNAL_CONNECT(graph_tseqttrace, "toggled", callback_graph_type, g);
+        SIGNAL_CONNECT(graph_tseqstevens, "toggled", callback_graph_type, g);
+        SIGNAL_CONNECT(graph_tput, "toggled", callback_graph_type, g);
+        SIGNAL_CONNECT(graph_rtt, "toggled", callback_graph_type, g);
+        SIGNAL_CONNECT(graph_init, "toggled", callback_graph_init_on_typechg,
+                       g);
 
        return graph_frame;
 }
@@ -1552,7 +1593,7 @@ static void callback_graph_type (GtkWidget *toggle, gpointer data)
        int old_type, new_type;
        struct graph *g = (struct graph * )data;
 
-       new_type = (int )gtk_object_get_data (GTK_OBJECT (toggle),"new-graph-type");
+       new_type = (int)OBJECT_GET_DATA(toggle,"new-graph-type");
 
        if (!GTK_TOGGLE_BUTTON (toggle)->active)
                return;
@@ -1582,7 +1623,7 @@ static void callback_graph_type (GtkWidget *toggle, gpointer data)
        graph_init_sequence (g);
 }
 
-static void callback_graph_init_on_typechg (GtkWidget *toggle, gpointer data)
+static void callback_graph_init_on_typechg (GtkWidget *toggle _U_, gpointer data)
 {
        ((struct graph * )data)->flags ^= GRAPH_INIT_ON_TYPE_CHANGE;
 }
@@ -1707,7 +1748,9 @@ static void graph_destroy (struct graph *g)
        /* gtk_widget_destroy (g->text); */
        gdk_gc_unref (g->fg_gc);
        gdk_gc_unref (g->bg_gc);
+#if GTK_MAJOR_VERSION < 2
        gdk_font_unref (g->font);
+#endif
        gdk_pixmap_unref (g->pixmap[0]);
        gdk_pixmap_unref (g->pixmap[1]);
        free (g->x_axis);
@@ -1736,10 +1779,13 @@ static void graph_destroy (struct graph *g)
 static void graph_segment_list_get (struct graph *g)
 {
        frame_data *ptr;
-       char pd[4096];
+       union wtap_pseudo_header pseudo_header;
+       char pd[WTAP_MAX_PACKET_SIZE];
        struct segment *segment=NULL, *last=NULL;
        struct segment current;
        int condition;
+       int err;
+       gchar *err_info;
 
        debug(DBS_FENTRY) puts ("graph_segment_list_get()");
        get_headers (cfile.current_frame, cfile.pd, &current);
@@ -1749,8 +1795,13 @@ static void graph_segment_list_get (struct graph *g)
                condition = COMPARE_ANY_DIR;
 
        for (ptr=cfile.plist; ptr; ptr=ptr->next) {
-               wtap_seek_read (cfile.wth, ptr->file_off, &cfile.pseudo_header,
-                                                       pd, 4096);
+               if (!wtap_seek_read (cfile.wth, ptr->file_off, &pseudo_header,
+                                    pd, ptr->cap_len, &err, &err_info)) {
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                                     cf_read_error_message(err, err_info),
+                                     cfile.filename);
+                       break;
+               }
                if (!segment)
                        segment = (struct segment * )malloc (sizeof (struct segment));
                        if (!segment)
@@ -1764,7 +1815,7 @@ static void graph_segment_list_get (struct graph *g)
                        segment->rel_usecs = ptr->rel_usecs;
                        segment->abs_secs = ptr->abs_secs;
                        segment->abs_usecs = ptr->abs_usecs;
-                       segment->data = ntohs (segment->iphdr.tot_len) -
+                       segment->data = g_ntohs (segment->iphdr.tot_len) -
                                                        4*IHL(&(segment->iphdr)) - 4*DOFF(segment->tcphdr);
                        if (g->segments) {
                                last->next = segment;
@@ -1783,6 +1834,7 @@ static int get_headers (frame_data *fd, char *pd, struct segment *hdrs)
 {
        struct ether_header *e;
        struct ppp_header   *p;
+       struct vlan_802_1_q *vlan;
        void *ip;
        void *tcp;
 
@@ -1802,15 +1854,40 @@ static int get_headers (frame_data *fd, char *pd, struct segment *hdrs)
        case WTAP_ENCAP_ETHERNET:
                /* It's Ethernet */
                e = (struct ether_header *)pd;
-               if (pntohs (&e->ether_type) != ETHERTYPE_IP)
-                       return FALSE;   /* not IP */
-               ip = e + 1;
+               switch (pntohs (&e->ether_type))
+               {
+                       case ETHERTYPE_IP:
+                               ip = e + 1;
+                               break;
+
+                       case ETHERTYPE_VLAN:
+                               /*
+                                * This code is awful but no more than the
+                                * rest of this file!!
+                                *
+                                * This really needs to be converted to
+                                * work as a TCP tap, so that the
+                                * regular dissectors take care of
+                                * finding the TCP header, rather than
+                                * doing our own *ad hoc* header
+                                * parsing.
+                                */ 
+                               vlan = (struct vlan_802_1_q *)(e + 1);
+                               if (ETHERTYPE_IP != pntohs(&vlan->type))
+                                       return FALSE;
+                               ip = vlan + 1;
+                               break;
+
+                       default:
+                               return FALSE;
+               }
                break;
 
        case WTAP_ENCAP_PPP:
+       case WTAP_ENCAP_PPP_WITH_PHDR:
                /* It's PPP */
                p = (struct ppp_header *)pd;
-               if (p->ppp_type != PPPTYPE_IP)
+               if (p->ppp_type != PPP_IP)
                        return FALSE;   /* not IP */
                ip = p + 1;
                break;
@@ -1824,7 +1901,7 @@ static int get_headers (frame_data *fd, char *pd, struct segment *hdrs)
                /* Those are the only encapsulation types we handle */
                return FALSE;
        }
-       if (((struct iphdr *)ip)->protocol != IPPROTO_TCP) {
+       if (((struct iphdr *)ip)->protocol != IP_PROTO_TCP) {
                /* printf ("transport protocol not TCP: %#1x\n", ip->protocol); */
                return FALSE;
        }
@@ -1928,21 +2005,32 @@ static void graph_title_pixmap_draw (struct graph *g)
 {
        int i;
 
-       gdk_draw_rectangle (g->title_pixmap, g->bg_gc, TRUE, 0, 0,
-                                                       g->x_axis->p.width, g->wp.y);
+       gdk_draw_rectangle(g->title_pixmap, g->bg_gc, TRUE, 0, 0,
+                           g->x_axis->p.width, g->wp.y);
        for (i=0; g->title[i]; i++) {
                gint w, h;
-               w = gdk_string_width (g->font, g->title[i]);
-               h = gdk_string_height (g->font, g->title[i]);
-               gdk_draw_string (g->title_pixmap, g->font, g->fg_gc,
-                                       g->wp.width/2 - w/2, 20+h + i*(h+3), g->title[i]);
+#if GTK_MAJOR_VERSION < 2
+               w = gdk_string_width(g->font, g->title[i]);
+               h = gdk_string_height(g->font, g->title[i]);
+               gdk_draw_string(g->title_pixmap, g->font, g->fg_gc,
+                                g->wp.width/2 - w/2, 20+h + i*(h+3),
+                                g->title[i]);
+#else
+                PangoLayout *layout;
+                layout = gtk_widget_create_pango_layout(g->drawing_area,
+                                                        g->title[i]);
+                pango_layout_get_pixel_size(layout, &w, &h);
+                gdk_draw_layout(g->title_pixmap, g->fg_gc,
+                                g->wp.width/2 - w/2, 20 + i*(h+3), layout);
+                g_object_unref(G_OBJECT(layout));
+#endif
        }
 }
 
 static void graph_title_pixmap_display (struct graph *g)
 {
        gdk_draw_pixmap (g->drawing_area->window, g->fg_gc, g->title_pixmap,
-                                               0, 0, g->wp.x, 0, g->x_axis->p.width, g->wp.y);
+                         0, 0, g->wp.x, 0, g->x_axis->p.width, g->wp.y);
 }
 
 static void graph_pixmaps_create (struct graph *g)
@@ -1974,6 +2062,9 @@ static void graph_pixmap_display (struct graph *g)
     gdk_draw_pixmap (g->drawing_area->window, g->fg_gc,
                                        g->pixmap[g->displayed], 0, 0, g->wp.x, g->wp.y,
                                        g->wp.width, g->wp.height);
+    if (g->cross.erase_needed) {
+       cross_xor(g, g->cross.x, g->cross.y);
+    }
 }
 
 static void graph_pixmaps_switch (struct graph *g)
@@ -2054,9 +2145,9 @@ static void draw_element_arc (struct graph *g, struct element *e)
        int x1, x2, y1, y2;
 
        x1 = (int )rint (e->p.arc.dim.x + g->geom.x - g->wp.x);
-       x2 = e->p.arc.dim.width;
+       x2 = (int )e->p.arc.dim.width;
        y1 = (int )rint (g->geom.height-1 - e->p.arc.dim.y + g->geom.y - g->wp.y);
-       y2 = e->p.arc.dim.height;
+       y2 = (int )e->p.arc.dim.height;
        if (x1<-x2 || x1>=g->wp.width || y1<-y2 || y1>=g->wp.height)
                return;
        debug(DBS_GRAPH_DRAWING) printf ("arc: (%d,%d)->(%d,%d)\n", x1, y1, x2, y2);
@@ -2104,6 +2195,9 @@ static void v_axis_pixmap_draw (struct axis *axis)
        double major_tick;
        int not_disp, rdigits, offset, imin, imax;
        double bottom, top, j, fl, corr;
+#if GTK_MAJOR_VERSION >= 2
+        PangoLayout *layout;
+#endif
 
        debug(DBS_FENTRY) puts ("v_axis_pixmap_draw()");
        bottom = (g->geom.height - (g->wp.height + g->wp.y + (-g->geom.y))) /
@@ -2127,7 +2221,7 @@ static void v_axis_pixmap_draw (struct axis *axis)
                                        axis->p.width, axis->p.height);
        /* axis */
        gdk_draw_line (axis->pixmap[not_disp], g->fg_gc, axis->p.width - 1,
-                       (axis->p.height-axis->s.height)/2.0, axis->s.width - 1,
+                       (gint) ((axis->p.height-axis->s.height)/2.0), axis->s.width - 1,
                        axis->p.height);
 
        offset = g->wp.y + (-g->geom.y);
@@ -2136,47 +2230,68 @@ static void v_axis_pixmap_draw (struct axis *axis)
 
        /* major ticks */
        major_tick = axis->major * g->zoom.y;
-       imin = (g->geom.height - offset + corr - g->wp.height) / major_tick + 1;
-       imax = (g->geom.height - offset + corr) / major_tick;
+       imin = (int) ((g->geom.height - offset + corr - g->wp.height) / major_tick + 1);
+       imax = (int) ((g->geom.height - offset + corr) / major_tick);
        for (i=imin; i <= imax; i++) {
                gint w, h;
                char desc[32];
-               int y = g->geom.height-1 - (int )rint (i * major_tick) -
-                                               offset + corr + axis->s.y;
+               int y = (int) (g->geom.height-1 - (int )rint (i * major_tick) -
+                                               offset + corr + axis->s.y);
 
-               debug(DBS_AXES_DRAWING) printf ("%f @ %d\n", i*axis->major + fl, y);
+               debug(DBS_AXES_DRAWING) printf("%f @ %d\n",
+                                               i*axis->major + fl, y);
                if (y < 0 || y > axis->p.height)
                        continue;
                gdk_draw_line (axis->pixmap[not_disp], g->fg_gc,
-                                               axis->s.width - 15, y, axis->s.width - 1, y);
+                               axis->s.width - 15, y, axis->s.width - 1, y);
                snprintf (desc, 32, "%.*f", rdigits, i*axis->major + fl);
-               w = gdk_string_width (g->font, desc);
-               h = gdk_string_height (g->font, desc);
-               gdk_draw_string (axis->pixmap[not_disp], g->font, g->fg_gc,
-                                       axis->s.width-15-4-w, y + h/2, desc);
+#if GTK_MAJOR_VERSION < 2
+               w = gdk_string_width(g->font, desc);
+               h = gdk_string_height(g->font, desc);
+               gdk_draw_string(axis->pixmap[not_disp], g->font, g->fg_gc,
+                                axis->s.width-15-4-w, y + h/2, desc);
+#else
+                layout = gtk_widget_create_pango_layout(g->drawing_area, desc);
+                pango_layout_get_pixel_size(layout, &w, &h);
+                gdk_draw_layout(axis->pixmap[not_disp], g->fg_gc,
+                                axis->s.width-14-4-w, y - h/2, layout);
+                g_object_unref(G_OBJECT(layout));
+#endif
        }
        /* minor ticks */
        if (axis->minor) {
                double minor_tick = axis->minor * g->zoom.y;
-               imin = (g->geom.height - offset + corr - g->wp.height)/minor_tick + 1;
-               imax = (g->geom.height - offset + corr) / minor_tick;
+               imin = (int) ((g->geom.height - offset + corr - g->wp.height)/minor_tick + 1);
+               imax = (int) ((g->geom.height - offset + corr) / minor_tick);
                for (i=imin; i <= imax; i++) {
-                       int y = g->geom.height-1 - (int )rint (i*minor_tick) -
-                                                       offset + corr + axis->s.y;
+                       int y = (int) (g->geom.height-1 - (int )rint (i*minor_tick) -
+                                                       offset + corr + axis->s.y);
 
                        debug (DBS_AXES_DRAWING) printf ("%f @ %d\n", i*axis->minor+fl, y);
                        if (y > 0 && y < axis->p.height)
                                gdk_draw_line (axis->pixmap[not_disp], g->fg_gc,
-                                                       axis->s.width - 8, y, axis->s.width - 1, y);
+                                               axis->s.width - 8, y,
+                                               axis->s.width - 1, y);
                }
        }
        for (i=0; axis->label[i]; i++) {
                gint w, h;
+#if GTK_MAJOR_VERSION < 2
                w = gdk_string_width (g->font, axis->label[i]);
                h = gdk_string_height (g->font, axis->label[i]);
-               gdk_draw_string (axis->pixmap[not_disp], g->font, g->fg_gc,
-                                       (axis->p.width - w)/2 , TITLEBAR_HEIGHT-15 - i*(h+3),
-                                       axis->label[i]);
+               gdk_draw_string(axis->pixmap[not_disp], g->font, g->fg_gc,
+                                (axis->p.width - w)/2 ,
+                                TITLEBAR_HEIGHT-15 - i*(h+3), axis->label[i]);
+#else
+                layout = gtk_widget_create_pango_layout(g->drawing_area,
+                                                        axis->label[i]);
+                pango_layout_get_pixel_size(layout, &w, &h);
+                gdk_draw_layout(axis->pixmap[not_disp], g->fg_gc,
+                                (axis->p.width - w)/2,
+                                TITLEBAR_HEIGHT-10 - i*(h+3) - h,
+                                layout);
+                g_object_unref(G_OBJECT(layout));
+#endif
        }
 }
 
@@ -2187,6 +2302,9 @@ static void h_axis_pixmap_draw (struct axis *axis)
        double major_tick, minor_tick;
        int not_disp, rdigits, offset, imin, imax;
        double left, right, j, fl, corr;
+#if GTK_MAJOR_VERSION >= 2
+        PangoLayout *layout;
+#endif
 
        debug(DBS_FENTRY) puts ("h_axis_pixmap_draw()");
        left = (g->wp.x-g->geom.x) /
@@ -2209,8 +2327,8 @@ static void h_axis_pixmap_draw (struct axis *axis)
        gdk_draw_rectangle (axis->pixmap[not_disp], g->bg_gc, TRUE, 0, 0,
                                        axis->p.width, axis->p.height);
        /* axis */
-       gdk_draw_line (axis->pixmap[not_disp], g->fg_gc, 0, 0,  
-                                               axis->s.width + (axis->p.width-axis->s.width)/2.0, 0);
+       gdk_draw_line (axis->pixmap[not_disp], g->fg_gc, 0, 0,
+                                               (gint) (axis->s.width + (axis->p.width-axis->s.width)/2.0), 0);
        offset = g->wp.x - g->geom.x;
 
        fl = floor (axis->min / axis->major) * axis->major;
@@ -2218,41 +2336,59 @@ static void h_axis_pixmap_draw (struct axis *axis)
 
        /* major ticks */
        major_tick = axis->major*g->zoom.x;
-       imin = (offset + corr) / major_tick + 1;
-       imax = (offset + corr + axis->s.width) / major_tick;
+       imin = (int) ((offset + corr) / major_tick + 1);
+       imax = (int) ((offset + corr + axis->s.width) / major_tick);
        for (i=imin; i <= imax; i++) {
                char desc[32];
                int w, h;
-               int x = (int )rint (i * major_tick) - offset - corr;
+               int x = (int ) (rint (i * major_tick) - offset - corr);
 
                /* printf ("%f @ %d\n", i*axis->major + fl, x); */
                if (x < 0 || x > axis->s.width)
                        continue;
                gdk_draw_line (axis->pixmap[not_disp], g->fg_gc, x, 0, x, 15);
                snprintf (desc, 32, "%.*f", rdigits, i*axis->major + fl);
+#if GTK_MAJOR_VERSION < 2
                w = gdk_string_width (g->font, desc);
                h = gdk_string_height (g->font, desc);
                gdk_draw_string (axis->pixmap[not_disp], g->font, g->fg_gc,
-                                               x - w/2, 15+h+4, desc);
+                                 x - w/2, 15+h+4, desc);
+#else
+                layout = gtk_widget_create_pango_layout(g->drawing_area, desc);
+                pango_layout_get_pixel_size(layout, &w, &h);
+                gdk_draw_layout(axis->pixmap[not_disp], g->fg_gc,
+                                x - w/2, 15+4, layout);
+                g_object_unref(G_OBJECT(layout));
+#endif
        }
        if (axis->minor > 0) {
                /* minor ticks */
                minor_tick = axis->minor*g->zoom.x;
-               imin = (offset + corr) / minor_tick + 1;
-               imax = (offset + corr + g->wp.width) / minor_tick;
+               imin = (int) ((offset + corr) / minor_tick + 1);
+               imax = (int) ((offset + corr + g->wp.width) / minor_tick);
                for (i=imin; i <= imax; i++) {
-                       int x = (int )rint (i * minor_tick) - offset - corr;
+                       int x = (int) (rint (i * minor_tick) - offset - corr);
                        if (x > 0 && x < axis->s.width)
                                gdk_draw_line (axis->pixmap[not_disp], g->fg_gc, x, 0, x, 8);
                }
        }
        for (i=0; axis->label[i]; i++) {
                gint w, h;
+#if GTK_MAJOR_VERSION < 2
                w = gdk_string_width (g->font, axis->label[i]);
                h = gdk_string_height (g->font, axis->label[i]);
-               gdk_draw_string (axis->pixmap[not_disp], g->font, g->fg_gc,
-                                       axis->s.width - w - 50, 15+2*h+15 + i*(h+3),
-                                       axis->label[i]);
+               gdk_draw_string(axis->pixmap[not_disp], g->font, g->fg_gc,
+                                axis->s.width - w - 50, 15+2*h+15 + i*(h+3),
+                                axis->label[i]);
+#else
+                layout = gtk_widget_create_pango_layout(g->drawing_area,
+                                                        axis->label[i]);
+                pango_layout_get_pixel_size(layout, &w, &h);
+                gdk_draw_layout(axis->pixmap[not_disp], g->fg_gc,
+                                axis->s.width - w - 50, 15+h+15 + i*(h+3),
+                                layout);
+                g_object_unref(G_OBJECT(layout));
+#endif
        }
 }
 
@@ -2343,10 +2479,10 @@ static void axis_compute_ticks (struct axis *axis, double x0, double xmax, int d
                        axis->minor = steps[jj] * pow (10, ii);
                        check_needed = TRUE;
                        diminished = TRUE;
-       
+
                        debug(DBS_AXES_TICKS) printf ("axis->minor diminished to %.1f\n",
                                                                                axis->minor);
-       
+
                        if (axis->minor*zoom < 10) {
                                debug(DBS_AXES_TICKS) printf ("refusing axis->minor of %f: "
                                        "axis->minor*zoom == %f\n", axis->minor, axis->minor*zoom);
@@ -2382,6 +2518,9 @@ static int get_label_dim (struct axis *axis, int dir, double label)
        double y;
        char str[32];
        int rdigits, dim;
+#if GTK_MAJOR_VERSION >= 2
+        PangoLayout *layout;
+#endif
 
         /* First, let's compute how many digits to the right of radix
         * we need to print */
@@ -2395,10 +2534,24 @@ static int get_label_dim (struct axis *axis, int dir, double label)
        snprintf (str, 32, "%.*f", rdigits, label);
        switch (dir) {
        case AXIS_HORIZONTAL:
-               dim = gdk_string_width (axis->g->font, str);
+#if GTK_MAJOR_VERSION < 2
+               dim = gdk_string_width(axis->g->font, str);
+#else
+                layout = gtk_widget_create_pango_layout(axis->g->drawing_area,
+                                                        str);
+                pango_layout_get_pixel_size(layout, &dim, NULL);
+                g_object_unref(G_OBJECT(layout));
+#endif
                break;
        case AXIS_VERTICAL:
-               dim = gdk_string_height (axis->g->font, str);
+#if GTK_MAJOR_VERSION < 2
+               dim = gdk_string_height(axis->g->font, str);
+#else
+                layout = gtk_widget_create_pango_layout(axis->g->drawing_area,
+                                                        str);
+                pango_layout_get_pixel_size(layout, NULL, &dim);
+                g_object_unref(G_OBJECT(layout));
+#endif
                break;
        default:
                puts ("initialize axis: an axis must be either horizontal or vertical");
@@ -2439,16 +2592,12 @@ static void graph_select_segment (struct graph *g, int x, int y)
                        case ELMT_RECT:
                                break;
                        case ELMT_LINE:
-                               if (line_detect_collision (e, x, y)) {
-                                       int row = e->parent->num - 1;
-                                       update_packet_list (row);
-                               }
+                               if (line_detect_collision (e, x, y))
+                                       goto_frame(&cfile, e->parent->num);
                                break;
                        case ELMT_ARC:
-                               if (arc_detect_collision (e, x, y)) {
-                                       int row = e->parent->num - 1;
-                                       update_packet_list (row);
-                               }
+                               if (arc_detect_collision (e, x, y))
+                                       goto_frame(&cfile, e->parent->num);
                                break;
                        default:
                                break;
@@ -2500,16 +2649,6 @@ static int arc_detect_collision (struct element *e, int x, int y)
                return FALSE;
 }
 
-static void update_packet_list (int row)
-{
-       select_packet (&cfile, row);
-       if (gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) !=
-                               GTK_VISIBILITY_FULL)
-               gtk_clist_moveto(GTK_CLIST(packet_list), row, -1, 0.5, 0.5);
-       GTK_CLIST(packet_list)->focus_row = row;
-       gtk_clist_select_row(GTK_CLIST(packet_list), row, -1);
-}
-
 static void cross_xor (struct graph *g, int x, int y)
 {
        if (x > g->wp.x && x < g->wp.x+g->wp.width &&
@@ -2545,11 +2684,9 @@ static void magnify_create (struct graph *g, int x, int y)
        mg = g->magnify.g = (struct graph * )malloc (sizeof (struct graph));
        memcpy ((void * )mg, (void * )g, sizeof (struct graph));
 
-       mg->toplevel = gtk_window_new (GTK_WINDOW_POPUP);
-       gtk_signal_connect (GTK_OBJECT (mg->toplevel), "realize",
-               GTK_SIGNAL_FUNC (window_icon_realize_cb), NULL);
+       mg->toplevel = window_new (GTK_WINDOW_POPUP, NULL);
        mg->drawing_area = mg->toplevel;
-       gtk_widget_set_usize (mg->toplevel, g->magnify.width, g->magnify.height);
+       WIDGET_SET_SIZE(mg->toplevel, g->magnify.width, g->magnify.height);
        gtk_widget_set_events (mg->drawing_area, GDK_EXPOSURE_MASK
                        /*              | GDK_ENTER_NOTIFY_MASK */
                        /*              | GDK_ALL_EVENTS_MASK   */
@@ -2721,10 +2858,10 @@ static gint configure_event (GtkWidget *widget, GdkEventConfigure *event)
        /* g->zoom.initial.x = g->zoom.x; */
        /* g->zoom.initial.y = g->zoom.y; */
 
-       g->geom.x = g->wp.x - (double )g->geom.width/cur_g_width *
-                                                       (g->wp.x - g->geom.x);
-       g->geom.y = g->wp.y - (double )g->geom.height/cur_g_height *
-                                                       (g->wp.y - g->geom.y);
+       g->geom.x = (int) (g->wp.x - (double )g->geom.width/cur_g_width *
+                                                       (g->wp.x - g->geom.x));
+       g->geom.y = (int) (g->wp.y - (double )g->geom.height/cur_g_height *
+                                                       (g->wp.y - g->geom.y));
 #if 0
        printf ("configure: graph: (%d,%d), (%d,%d); viewport: (%d,%d), (%d,%d); "
                                "zooms: (%f,%f)\n", g->geom.x, g->geom.y, g->geom.width,
@@ -2859,12 +2996,13 @@ static gint button_press_event (GtkWidget *widget, GdkEventButton *event)
                                g->wp.height, g->zoom.x, g->zoom.y);
 #endif
                graph_element_lists_make (g);
+               g->cross.erase_needed = 0;
                graph_display (g);
                axis_display (g->y_axis);
                axis_display (g->x_axis);
                update_zoom_spins (g);
                if (g->cross.draw)
-                       cross_draw (g, event->x, event->y);
+                       cross_draw (g, (int) event->x, (int) event->y);
 #ifndef WIN32
        } else if (event->button == 1) {
                graph_select_segment (g, (int )event->x, (int )event->y);
@@ -2890,11 +3028,11 @@ static gint motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
        if (event->is_hint)
                gdk_window_get_pointer (event->window, &x, &y, &state);
        else {
-               x = event->x;
-               y = event->y;
+               x = (int) event->x;
+               y = (int) event->y;
                state = event->state;
        }
-    
+
        /* Testing just (state & GDK_BUTTON1_MASK) is not enough since when button1
         * is pressed while pointer is in motion, we will receive one more motion
         * notify *before* we get the button press. This last motion notify works
@@ -2912,6 +3050,7 @@ static gint motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
                                g->geom.x = g->wp.width + g->wp.x - g->geom.width;
                        if (g->wp.y + g->wp.height > g->geom.y + g->geom.height)
                                g->geom.y = g->wp.height + g->wp.y - g->geom.height;
+                       g->cross.erase_needed = 0;
                        graph_display (g);
                        axis_display (g->y_axis);
                        axis_display (g->x_axis);
@@ -2931,7 +3070,7 @@ static gint motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
                if (g->cross.draw)
                        cross_draw (g, x, y);
        }
-  
+
        return TRUE;
 }
 
@@ -3008,7 +3147,7 @@ static gint key_release_event (GtkWidget *widget, GdkEventKey *event)
        return TRUE;
 }
 
-static gint leave_notify_event (GtkWidget *widget, GdkEventCrossing *event)
+static gint leave_notify_event (GtkWidget *widget, GdkEventCrossing *event _U_)
 {
        struct graph *g;
 
@@ -3022,7 +3161,7 @@ static gint leave_notify_event (GtkWidget *widget, GdkEventCrossing *event)
        return TRUE;
 }
 
-static gint enter_notify_event (GtkWidget *widget, GdkEventCrossing *event)
+static gint enter_notify_event (GtkWidget *widget, GdkEventCrossing *event _U_)
 {
        struct graph *g;
 
@@ -3148,7 +3287,10 @@ static void tseq_stevens_initialize (struct graph *g)
 static void tseq_stevens_get_bounds (struct graph *g)
 {
        struct segment *tmp, *last, *first;
-       double t0, tmax, y0, ymax;
+       double t, t0, tmax, ymax;
+       guint32 seq_base;
+       guint32 seq_cur;
+       guint32 ack_base = 0;
 
        for (first=g->segments; first->next; first=first->next) {
                if (compare_headers (g->current, first, COMPARE_CURR_DIR))
@@ -3156,15 +3298,27 @@ static void tseq_stevens_get_bounds (struct graph *g)
        }
        last = NULL;
        ymax = 0;
+       tmax = 0;
+       
+       seq_base = g_ntohl (first->tcphdr.seq);
        for (tmp=g->segments; tmp; tmp=tmp->next) {
                unsigned int highest_byte_num;
                last = tmp;
-               if (compare_headers (g->current, tmp, COMPARE_CURR_DIR))
-                       highest_byte_num = ntohl (tmp->tcphdr.seq) + tmp->data;
-               else
-                       highest_byte_num = ntohl (tmp->tcphdr.ack_seq);
+               if (compare_headers (g->current, tmp, COMPARE_CURR_DIR)) {
+                       seq_cur = g_ntohl (tmp->tcphdr.seq) -seq_base;
+                       highest_byte_num = seq_cur + tmp->data;
+               }
+               else {
+                       seq_cur = g_ntohl (tmp->tcphdr.ack_seq);
+                       if (!ack_base)
+                               ack_base = seq_cur;
+                       highest_byte_num = seq_cur - ack_base;
+               }
                if (highest_byte_num > ymax)
                        ymax = highest_byte_num;
+               t = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+               if (t > tmax)
+                       tmax = t;
        }
        if (!last) {
                puts ("tseq_stevens_get_bounds: segment list corrupted!");
@@ -3172,13 +3326,10 @@ static void tseq_stevens_get_bounds (struct graph *g)
        }
 
        t0 = g->segments->rel_secs + g->segments->rel_usecs / 1000000.0;
-       tmax = last->rel_secs + last->rel_usecs / 1000000.0;
-       y0 = ntohl (first->tcphdr.seq);
-
        g->bounds.x0 = t0;
-       g->bounds.y0 = y0;
+       g->bounds.y0 = seq_base;
        g->bounds.width = tmax - t0;
-       g->bounds.height = ymax - y0;
+       g->bounds.height = ymax;
        g->zoom.x = (g->geom.width - 1) / g->bounds.width;
        g->zoom.y = (g->geom.height -1) / g->bounds.height;
 }
@@ -3188,6 +3339,8 @@ static void tseq_stevens_make_elmtlist (struct graph *g)
        struct segment *tmp;
        struct element *elements, *e;
        double x0 = g->bounds.x0, y0 = g->bounds.y0;
+       guint32 seq_base = (guint32) y0;
+       guint32 seq_cur;
 
        debug(DBS_FENTRY) puts ("tseq_stevens_make_elmtlist()");
        if (g->elists->elements == NULL) {
@@ -3201,9 +3354,9 @@ static void tseq_stevens_make_elmtlist (struct graph *g)
 
                if (!compare_headers (g->current, tmp, COMPARE_CURR_DIR))
                        continue;
-
+               seq_cur = g_ntohl (tmp->tcphdr.seq) - seq_base;
                secs = g->zoom.x * (tmp->rel_secs + tmp->rel_usecs / 1000000.0 - x0);
-               seqno = g->zoom.y * (ntohl (tmp->tcphdr.seq) - y0);
+               seqno = g->zoom.y * seq_cur;
 
                e->type = ELMT_ARC;
                e->parent = tmp;
@@ -3255,14 +3408,50 @@ static void tseq_tcptrace_read_config (struct graph *g)
        g->s.tseq_tcptrace.gc_ack[0] = gdk_gc_new (g->drawing_area->window);
        g->s.tseq_tcptrace.gc_ack[1] = gdk_gc_new (g->drawing_area->window);
        colormap = gdk_window_get_colormap (g->drawing_area->window);
-       gdk_color_parse ("black", &color);
-       gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE);
+       if (!gdk_color_parse ("black", &color)) {
+               /*
+                * XXX - do more than just warn.
+                */
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                   "Could not parse color black.");
+       }
+       if (!gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE)) {
+               /*
+                * XXX - do more than just warn.
+                */
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                   "Could not allocate color black.");
+       }
        gdk_gc_set_foreground (g->s.tseq_tcptrace.gc_seq, &color);
-       gdk_color_parse ("LightSlateGray", &color);
-       gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE);
+       if (!gdk_color_parse ("LightSlateGray", &color)) {
+               /*
+                * XXX - do more than just warn.
+                */
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                   "Could not parse color LightSlateGray.");
+       }
+       if (!gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE)) {
+               /*
+                * XXX - do more than just warn.
+                */
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                   "Could not allocate color LightSlateGray.");
+       }
        gdk_gc_set_foreground (g->s.tseq_tcptrace.gc_ack[0], &color);
-       gdk_color_parse ("LightGray", &color);
-       gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE);
+       if (!gdk_color_parse ("LightGray", &color)) {
+               /*
+                * XXX - do more than just warn.
+                */
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                   "Could not parse color LightGray.");
+       }
+       if (!gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE)) {
+               /*
+                * XXX - do more than just warn.
+                */
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+                   "Could not allocate color LightGray.");
+       }
        gdk_gc_set_foreground (g->s.tseq_tcptrace.gc_ack[1], &color);
 
        g->elists->next = (struct element_list * )
@@ -3291,6 +3480,8 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
        double p_t; /* ackno, window and time of previous segment */
        double p_ackno, p_win;
        int toggle=0;
+       guint32 seq_base;
+       guint32 seq_cur;
 
        debug(DBS_FENTRY) puts ("tseq_tcptrace_make_elmtlist()");
 
@@ -3308,18 +3499,19 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
 
        x0 = g->bounds.x0;
        y0 = g->bounds.y0;
+       seq_base = (guint32) y0;
        /* initialize "previous" values */
        for (tmp=g->segments; tmp; tmp=tmp->next)
                if (!compare_headers (g->current, tmp, COMPARE_CURR_DIR))
                        break;
        /*
-       p_ackno = (unsigned int )(g->zoom.y * (ntohl (tmp->tcphdr.ack_seq) - y0));
+       p_ackno = (unsigned int )(g->zoom.y * (g_ntohl (tmp->tcphdr.ack_seq) - y0));
         */
        p_ackno = 0;
-       p_win = g->zoom.y * ntohs (tmp->tcphdr.window);
+       p_win = g->zoom.y * g_ntohs (tmp->tcphdr.window);
        p_t = g->segments->rel_secs + g->segments->rel_usecs/1000000.0 - x0;
        for (tmp=g->segments; tmp; tmp=tmp->next) {
-               double secs, seqno, data;
+               double secs, data;
                double x;
 
                secs = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
@@ -3329,14 +3521,14 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
                        /* forward direction -> we need seqno and amount of data */
                        double y1, y2;
 
-                       seqno = ntohl (tmp->tcphdr.seq);
+                       seq_cur = g_ntohl (tmp->tcphdr.seq) -seq_base;
                        if (TCP_SYN (tmp->tcphdr))
                                data = 1;
                        else
                                data = tmp->data;
 
-                       y1 = g->zoom.y * (seqno - y0);
-                       y2 = g->zoom.y * (seqno - y0 + data);
+                       y1 = g->zoom.y * (seq_cur);
+                       y2 = g->zoom.y * (seq_cur + data);
                        e1->type = ELMT_LINE;
                        e1->parent = tmp;
                        e1->gc = g->s.tseq_tcptrace.gc_seq;
@@ -3364,8 +3556,9 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
                                /* SYN's have ACK==0 and are useless here */
                                continue;
                        /* backward direction -> we need ackno and window */
-                       ackno = (ntohl (tmp->tcphdr.ack_seq) - y0) * g->zoom.y;
-                       win = ntohs (tmp->tcphdr.window) * g->zoom.y;
+                       seq_cur = g_ntohl (tmp->tcphdr.ack_seq) - seq_base;
+                       ackno = seq_cur * g->zoom.y;
+                       win = g_ntohs (tmp->tcphdr.window) * g->zoom.y;
 
                        /* ack line */
                        e0->type = ELMT_LINE;
@@ -3485,7 +3678,7 @@ static void tput_initialize (struct graph *g)
        struct segment *tmp, *oldest, *last;
        int i, sum=0;
        double dtime, tput, tputmax=0;
-       double t0, tmax, y0, ymax;
+       double t, t0, tmax = 0, y0, ymax;
 
        debug(DBS_FENTRY) puts ("tput_initialize()");
 
@@ -3504,10 +3697,12 @@ static void tput_initialize (struct graph *g)
                debug(DBS_TPUT_ELMTS) printf ("tput=%f\n", tput);
                if (tput > tputmax)
                        tputmax = tput;
+               t = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
+               if (t > tmax)
+                       tmax = t;
        }
 
        t0 = g->segments->rel_secs + g->segments->rel_usecs / 1000000.0;
-       tmax = last->rel_secs + last->rel_usecs / 1000000.0;
        y0 = 0;
        ymax = tputmax;
 
@@ -3576,7 +3771,9 @@ static void rtt_initialize (struct graph *g)
        struct segment *tmp, *first=NULL;
        struct unack *unack = NULL, *u;
        double rttmax=0;
-       double x0, xmax=0, y0, ymax;
+       double x0, y0, ymax;
+       guint32 xmax = 0;
+       guint32 seq_base = 0;
 
        debug(DBS_FENTRY) puts ("rtt_initialize()");
 
@@ -3584,11 +3781,13 @@ static void rtt_initialize (struct graph *g)
 
        for (tmp=g->segments; tmp; tmp=tmp->next) {
                if (compare_headers (g->current, tmp, COMPARE_CURR_DIR)) {
-                       unsigned int seqno = ntohl (tmp->tcphdr.seq);
-                       
-                       if (!first)
-                               first= tmp;
+                       guint32 seqno = g_ntohl (tmp->tcphdr.seq);
 
+                       if (!first) {
+                               first= tmp;
+                               seq_base = seqno;
+                       }
+                       seqno -= seq_base;
                        if (tmp->data && !rtt_is_retrans (unack, seqno)) {
                                double time = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
                                u = rtt_get_new_unack (time, seqno);
@@ -3598,8 +3797,8 @@ static void rtt_initialize (struct graph *g)
 
                        if (seqno + tmp->data > xmax)
                                xmax = seqno + tmp->data;
-               } else {
-                       unsigned int ackno = ntohl (tmp->tcphdr.ack_seq);
+               } else if (first) {
+                       guint32 ackno = g_ntohl (tmp->tcphdr.ack_seq) -seq_base;
                        double time = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
                        struct unack *v;
 
@@ -3615,13 +3814,13 @@ static void rtt_initialize (struct graph *g)
                }
        }
 
-       x0 = ntohl (first->tcphdr.seq);
+       x0 = seq_base;
        y0 = 0;
        ymax = rttmax;
 
        g->bounds.x0 = x0;
        g->bounds.y0 = y0;
-       g->bounds.width = xmax - x0;
+       g->bounds.width = xmax;
        g->bounds.height = ymax - y0;
        g->zoom.x = g->geom.width / g->bounds.width;
        g->zoom.y = g->geom.height / g->bounds.height;
@@ -3632,7 +3831,7 @@ static int rtt_is_retrans (struct unack *list, unsigned int seqno)
        struct unack *u;
 
        for (u=list; u; u=u->next)
-               if (u->seqno == seqno)
+               if (u->seqno== seqno)
                        return TRUE;
 
        return FALSE;
@@ -3689,6 +3888,7 @@ static void rtt_make_elmtlist (struct graph *g)
        struct segment *tmp;
        struct unack *unack = NULL, *u;
        struct element *elements, *e;
+       guint32 seq_base = (guint32) g->bounds.x0;
 
        debug(DBS_FENTRY) puts ("rtt_make_elmtlist()");
 
@@ -3700,7 +3900,7 @@ static void rtt_make_elmtlist (struct graph *g)
 
        for (tmp=g->segments; tmp; tmp=tmp->next) {
                if (compare_headers (g->current, tmp, COMPARE_CURR_DIR)) {
-                       unsigned int seqno = ntohl (tmp->tcphdr.seq);
+                       guint32 seqno = g_ntohl (tmp->tcphdr.seq) -seq_base;
 
                        if (tmp->data && !rtt_is_retrans (unack, seqno)) {
                                double time = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
@@ -3709,7 +3909,7 @@ static void rtt_make_elmtlist (struct graph *g)
                                rtt_put_unack_on_list (&unack, u);
                        }
                } else {
-                       unsigned int ackno = ntohl (tmp->tcphdr.ack_seq);
+                       guint32 ackno = g_ntohl (tmp->tcphdr.ack_seq) -seq_base;
                        double time = tmp->rel_secs + tmp->rel_usecs / 1000000.0;
                        struct unack *v;
 
@@ -3722,8 +3922,7 @@ static void rtt_make_elmtlist (struct graph *g)
                                        e->gc = g->fg_gc;
                                        e->p.arc.dim.width = g->s.rtt.width;
                                        e->p.arc.dim.height = g->s.rtt.height;
-                                       e->p.arc.dim.x = g->zoom.x * (u->seqno - g->bounds.x0)
-                                                                                                               - g->s.rtt.width/2.0;
+                                       e->p.arc.dim.x = g->zoom.x * u->seqno - g->s.rtt.width/2.0;
                                        e->p.arc.dim.y = g->zoom.y * rtt + g->s.rtt.height/2.0;
                                        e->p.arc.filled = TRUE;
                                        e->p.arc.angle1 = 0;
@@ -3750,7 +3949,7 @@ static void rtt_toggle_seq_origin (struct graph *g)
                g->x_axis->min = 0;
 }
 
-#ifdef WIN32
+#if defined(WIN32) && !defined(__MINGW32__)
 /* replacement of Unix rint() for Windows */
 static int rint (double x)
 {
@@ -3765,3 +3964,24 @@ static int rint (double x)
        return(i);
 }
 #endif
+
+
+gboolean tcp_graph_selected_packet_enabled(frame_data *current_frame, epan_dissect_t *edt) 
+{
+    return current_frame != NULL ? (edt->pi.ipproto == IP_PROTO_TCP) : FALSE;
+}
+
+
+void
+register_tap_listener_tcp_graph(void)
+{
+    register_tap_menu_item("TCP/Stream Analysis/Time-Sequence Graph (Stevens)", REGISTER_TAP_LAYER_TRANSPORT,
+        tcp_graph_cb, tcp_graph_selected_packet_enabled, NULL, GINT_TO_POINTER(0));
+    register_tap_menu_item("TCP/Stream Analysis/Time-Sequence Graph (tcptrace)", REGISTER_TAP_LAYER_TRANSPORT,
+        tcp_graph_cb, tcp_graph_selected_packet_enabled, NULL, GINT_TO_POINTER(1));
+    register_tap_menu_item("TCP/Stream Analysis/Throughput Graph", REGISTER_TAP_LAYER_TRANSPORT,
+        tcp_graph_cb, tcp_graph_selected_packet_enabled, NULL, GINT_TO_POINTER(2));
+    register_tap_menu_item("TCP/Stream Analysis/Round Trip Time Graph", REGISTER_TAP_LAYER_TRANSPORT,
+        tcp_graph_cb, tcp_graph_selected_packet_enabled, NULL, GINT_TO_POINTER(3));
+}
+