Calculate skew and clock drift, make it possible to copy the label.
[obnox/wireshark/wip.git] / gtk / rtp_analysis.c
index c6c9ca999a45264d1c9b8721c5427fd6a1ed672e..7a19105a2edd0b3e28872dca230fec1dbd1e35a2 100644 (file)
@@ -1,5 +1,5 @@
 /* rtp_analysis.c
- * RTP analysis addition for ethereal
+ * RTP analysis addition for Wireshark
  *
  * $Id$
  *
  *
  * Graph. Copyright 2004, Verso Technology
  * By Alejandro Vaquero <alejandro.vaquero@verso.com>
- * Based on io_stat.c by Ronnie Sahlberg 
+ * Based on io_stat.c by Ronnie Sahlberg
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
-
-/*do not define this symbol. will be added soon*/
-/*#define USE_CONVERSATION_GRAPH 1*/
-
-#include "rtp_analysis.h"
-#include "rtp_stream.h"
-#include "rtp_stream_dlg.h"
-
-#ifdef USE_CONVERSATION_GRAPH
-#include "../graph/graph.h"
-#endif
-
-#include <epan/epan_dissect.h>
-#include <epan/filesystem.h>
-
-#include "util.h"
-#include <epan/tap.h>
-#include "register.h"
-#include <epan/dissectors/packet-rtp.h>
-#include "g711.h"
-#include "rtp_pt.h"
-#include <epan/addr_resolv.h>
-
-/* in /gtk ... */
-#include <gtk/gtk.h>
-#include "gtkglobals.h"
-
-#include <epan/stat_cmd_args.h>
-#include "dlg_utils.h"
-#include "gui_utils.h"
-#include "alert_box.h"
-#include "simple_dialog.h"
-#include "../stat_menu.h"
-#include "gui_stat_menu.h"
-#include "main.h"
-#include "progress_dlg.h"
-#include "compat_macros.h"
-#include "../color.h"
-
-#include "image/clist_ascend.xpm"
-#include "image/clist_descend.xpm"
-
 #include <math.h>
-#include <fcntl.h>
 #include <string.h>
 #include <locale.h>
 
 #include <fcntl.h>
 #endif
 
-#ifdef HAVE_IO_H
-#include <io.h> /* open/close on win32 */
-#endif
+#include <gtk/gtk.h>
 
-/* Win32 needs the O_BINARY flag for open() */
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
+#include <epan/epan_dissect.h>
+#include <epan/filesystem.h>
+#include <epan/pint.h>
+#include <epan/tap.h>
+#include <epan/dissectors/packet-rtp.h>
+#include <epan/rtp_pt.h>
+#include <epan/addr_resolv.h>
+#include <epan/stat_cmd_args.h>
+#include <epan/strutil.h>
 
+#include "../util.h"
+#include "../register.h"
+#include "../g711.h"
+#include "../alert_box.h"
+#include "../simple_dialog.h"
+#include "../stat_menu.h"
+#include "../progress_dlg.h"
+#include "../color.h"
+#include "../tempfile.h"
+#include <wsutil/file_util.h>
+
+#include "gtk/gtkglobals.h"
+#include "gtk/dlg_utils.h"
+#include "gtk/file_dlg.h"
+#include "gtk/gui_utils.h"
+#include "gtk/gui_stat_menu.h"
+#include "gtk/main.h"
+#include "gtk/rtp_analysis.h"
+#include "gtk/rtp_stream.h"
+#include "gtk/rtp_stream_dlg.h"
+
+enum
+{
+   PACKET_COLUMN,
+   SEQUENCE_COLUMN,
+   DELTA_COLUMN,
+   JITTER_COLUMN,
+   SKEW_COLUMN,
+   IPBW_COLUMN,
+   MARKER_COLUMN,
+   STATUS_COLUMN,
+   DATE_COLUMN,
+   LENGTH_COLUMN,
+   FOREGROUND_COLOR_COL,
+   BACKGROUND_COLOR_COL,
+   N_COLUMN /* The number of columns */
+};
 /****************************************************************************/
 
-typedef struct column_arrows {
-       GtkWidget *table;
-       GtkWidget *ascend_pm;
-       GtkWidget *descend_pm;
-} column_arrows;
-
 #define NUM_COLS 9
 #define NUM_GRAPH_ITEMS 100000
 #define MAX_YSCALE 16
@@ -133,7 +124,7 @@ typedef struct _dialog_graph_graph_item_t {
 } dialog_graph_graph_item_t;
 
 typedef struct _dialog_graph_graph_t {
-       struct _user_data_t *ud;        
+       struct _user_data_t *ud;
         dialog_graph_graph_item_t items[NUM_GRAPH_ITEMS];
         int plot_style;
         gboolean display;
@@ -162,23 +153,24 @@ typedef struct _dialog_graph_t {
         int pixels_per_tick;
         int max_y_units;
        double start_time;
-} dialog_graph_t;      
+} dialog_graph_t;
 
 typedef struct _dialog_data_t {
        GtkWidget *window;
-       GtkCList *clist_fwd;
-       GtkCList *clist_rev;
+       GtkWidget *list_fwd;
+       GtkTreeIter  iter;
+       GtkWidget *list_rev;
        GtkWidget *label_stats_fwd;
        GtkWidget *label_stats_rev;
-       column_arrows *col_arrows_fwd;
-       column_arrows *col_arrows_rev;
+       GtkWidget *selected_list;
+       guint   number_of_nok;
+       GtkTreeSelection *selected_list_sel;
+       gint selected_list_row;
        GtkWidget *notebook;
-       GtkCList *selected_clist;
        GtkWidget *save_voice_as_w;
        GtkWidget *save_csv_as_w;
        gint notebook_signal_id;
-       gint selected_row;
-        dialog_graph_t dialog_graph;
+    dialog_graph_t dialog_graph;
 #ifdef USE_CONVERSATION_GRAPH
        GtkWidget *graph_window;
 #endif
@@ -186,60 +178,6 @@ typedef struct _dialog_data_t {
 
 #define OK_TEXT "[ Ok ]"
 
-typedef struct _key_value {
-  guint32  key;
-  guint32  value;
-} key_value;
-
-
-/* RTP sampling clock rates for fixed payload types as defined in
- http://www.iana.org/assignments/rtp-parameters */
-static const key_value clock_map[] = {
-       {PT_PCMU,       8000},
-       {PT_1016,       8000},
-       {PT_G721,       8000},
-       {PT_GSM,        8000},
-       {PT_G723,       8000},
-       {PT_DVI4_8000,  8000},
-       {PT_DVI4_16000, 16000},
-       {PT_LPC,        8000},
-       {PT_PCMA,       8000},
-       {PT_G722,       8000},
-       {PT_L16_STEREO, 44100},
-       {PT_L16_MONO,   44100},
-       {PT_QCELP,      8000},
-       {PT_CN,         8000},
-       {PT_MPA,        90000},
-       {PT_G728,       8000},
-       {PT_G728,       8000},
-       {PT_DVI4_11025, 11025},
-       {PT_DVI4_22050, 22050},
-       {PT_G729,       8000},
-       {PT_CN_OLD,     8000},
-       {PT_CELB,       90000},
-       {PT_JPEG,       90000},
-       {PT_NV,         90000},
-       {PT_H261,       90000},
-       {PT_MPV,        90000},
-       {PT_MP2T,       90000},
-       {PT_H263,       90000},
-};
-
-#define NUM_CLOCK_VALUES       (sizeof clock_map / sizeof clock_map[0])
-
-static guint32
-get_clock_rate(guint32 key)
-{
-       size_t i;
-
-       for (i = 0; i < NUM_CLOCK_VALUES; i++) {
-               if (clock_map[i].key == key)
-                       return clock_map[i].value;
-       }
-       return 1;
-}
-
-
 /* type of error when saving voice in a file didn't succeed */
 typedef enum {
        TAP_RTP_WRONG_CODEC,
@@ -248,12 +186,7 @@ typedef enum {
        TAP_RTP_SHORT_FRAME,
        TAP_RTP_FILE_OPEN_ERROR,
        TAP_RTP_NO_DATA
-} error_type_t; 
-
-#if GTK_MAJOR_VERSION < 2
-GtkRcStyle *rc_style;
-GdkColormap *colormap;
-#endif
+} error_type_t;
 
 typedef struct _tap_rtp_save_info_t {
        FILE *fp;
@@ -271,7 +204,10 @@ struct _info_direction {
 
 #define TMPNAMSIZE 100
 
-/* structure that holds general information about the connection 
+#define SILENCE_PCMU   (guint8)0xFF
+#define SILENCE_PCMA   (guint8)0x55
+
+/* structure that holds general information about the connection
 * and structures for both directions */
 typedef struct _user_data_t {
        /* tap associated data*/
@@ -303,11 +239,12 @@ typedef struct _user_data_t {
 
 
 /* Column titles. */
-static const gchar *titles[9] =  {
+static const gchar *titles[10] =  {
        "Packet",
        "Sequence",
        "Delta (ms)",
        "Jitter (ms)",
+       "Skew(ms)",
        "IP BW (kbps)",
        "Marker",
        "Status",
@@ -316,18 +253,21 @@ static const gchar *titles[9] =  {
 };
 
 #define SAVE_FORWARD_DIRECTION_MASK 0x01
-#define SAVE_REVERSE_DIRECTION_MASK 0x02       
-#define SAVE_BOTH_DIRECTION_MASK       (SAVE_FORWARD_DIRECTION_MASK|SAVE_REVERSE_DIRECTION_MASK) 
+#define SAVE_REVERSE_DIRECTION_MASK 0x02
+#define SAVE_BOTH_DIRECTION_MASK       (SAVE_FORWARD_DIRECTION_MASK|SAVE_REVERSE_DIRECTION_MASK)
 
+#define SAVE_NONE_FORMAT 0
+#define SAVE_WAV_FORMAT        1
 #define SAVE_AU_FORMAT 2
+#define SAVE_SW_FORMAT 3
 #define SAVE_RAW_FORMAT        4
 
 
-static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_);
+static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data);
 /****************************************************************************/
 static void enable_graph(dialog_graph_graph_t *dgg)
 {
-        
+
         dgg->display=TRUE;
 
 }
@@ -395,9 +335,9 @@ rtp_reset(void *user_data_arg)
        user_data->forward.saveinfo.saved = FALSE;
        user_data->reversed.saveinfo.saved = FALSE;
 
-       /* clear the dialog box clists */
-       gtk_clist_clear(GTK_CLIST(user_data->dlg.clist_fwd));
-       gtk_clist_clear(GTK_CLIST(user_data->dlg.clist_rev));
+       /* clear the dialog box lists */
+       gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(user_data->dlg.list_fwd))));
+       gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(user_data->dlg.list_rev))));
 
        /* reset graph info */
        dialog_graph_reset(user_data);
@@ -405,7 +345,7 @@ rtp_reset(void *user_data_arg)
 #ifdef USE_CONVERSATION_GRAPH
        if (user_data->dlg.graph_window != NULL)
                window_destroy(user_data->dlg.graph_window);
-       
+
        g_array_free(user_data->series_fwd.value_pairs, TRUE);
        user_data->series_fwd.value_pairs = g_array_new(FALSE, FALSE, sizeof(value_pair_t));
 
@@ -415,13 +355,13 @@ rtp_reset(void *user_data_arg)
 
        /* XXX check for error at fclose? */
        if (user_data->forward.saveinfo.fp != NULL)
-               fclose(user_data->forward.saveinfo.fp); 
+               fclose(user_data->forward.saveinfo.fp);
        if (user_data->reversed.saveinfo.fp != NULL)
-               fclose(user_data->reversed.saveinfo.fp); 
-       user_data->forward.saveinfo.fp = fopen(user_data->f_tempname, "wb"); 
+               fclose(user_data->reversed.saveinfo.fp);
+       user_data->forward.saveinfo.fp = ws_fopen(user_data->f_tempname, "wb");
        if (user_data->forward.saveinfo.fp == NULL)
                user_data->forward.saveinfo.error_type = TAP_RTP_FILE_OPEN_ERROR;
-       user_data->reversed.saveinfo.fp = fopen(user_data->r_tempname, "wb");
+       user_data->reversed.saveinfo.fp = ws_fopen(user_data->r_tempname, "wb");
        if (user_data->reversed.saveinfo.fp == NULL)
                user_data->reversed.saveinfo.error_type = TAP_RTP_FILE_OPEN_ERROR;
        return;
@@ -491,15 +431,15 @@ static void rtp_draw(void *prs _U_)
 }
 
 /* forward declarations */
-static void add_to_clist(GtkCList *clist, guint32 number, guint16 seq_num,
-                         double delta, double jitter, double bandwidth, gchar *status, gboolean marker,
-                         gchar *timeStr, guint32 pkt_len, GdkColor *color);
+static void add_to_list(GtkWidget *list, user_data_t * user_data, guint32 number, guint16 seq_num,
+                         double delta, double jitter, double skew ,double bandwidth, gchar *status, gboolean marker,
+                         gchar *timeStr, guint32 pkt_len,gchar *color_str, guint32 flags);
 
-static int rtp_packet_add_info(GtkCList *clist,
+static int rtp_packet_add_info(GtkWidget *list, user_data_t * user_data,
        tap_rtp_stat_t *statinfo, packet_info *pinfo,
        const struct _rtp_info *rtpinfo);
 
-static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo, 
+static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
                                    tap_rtp_stat_t *statinfo,
                                    packet_info *pinfo,
                                    const struct _rtp_info *rtpinfo);
@@ -534,7 +474,7 @@ static int rtp_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *e
                rtp_packet_analyse(&(user_data->forward.statinfo), pinfo, rtpinfo);
                rtp_packet_add_graph(&(user_data->dlg.dialog_graph.graph[GRAPH_FWD_JITTER]), &(user_data->forward.statinfo), pinfo, (guint32)(user_data->forward.statinfo.jitter*1000000));
                rtp_packet_add_graph(&(user_data->dlg.dialog_graph.graph[GRAPH_FWD_DIFF]), &(user_data->forward.statinfo), pinfo, (guint32)(user_data->forward.statinfo.diff*1000000));
-               rtp_packet_add_info(user_data->dlg.clist_fwd,
+               rtp_packet_add_info(user_data->dlg.list_fwd, user_data,
                        &(user_data->forward.statinfo), pinfo, rtpinfo);
                rtp_packet_save_payload(&(user_data->forward.saveinfo),
                        &(user_data->forward.statinfo), pinfo, rtpinfo);
@@ -553,7 +493,7 @@ static int rtp_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *e
                rtp_packet_analyse(&(user_data->reversed.statinfo), pinfo, rtpinfo);
                rtp_packet_add_graph(&(user_data->dlg.dialog_graph.graph[GRAPH_REV_JITTER]), &(user_data->reversed.statinfo), pinfo, (guint32)(user_data->reversed.statinfo.jitter*1000000));
                rtp_packet_add_graph(&(user_data->dlg.dialog_graph.graph[GRAPH_REV_DIFF]), &(user_data->reversed.statinfo), pinfo, (guint32)(user_data->reversed.statinfo.diff*1000000));
-               rtp_packet_add_info(user_data->dlg.clist_rev,
+               rtp_packet_add_info(user_data->dlg.list_rev, user_data,
                        &(user_data->reversed.statinfo), pinfo, rtpinfo);
                rtp_packet_save_payload(&(user_data->reversed.saveinfo),
                        &(user_data->reversed.statinfo), pinfo, rtpinfo);
@@ -562,181 +502,17 @@ static int rtp_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *e
        return 0;
 }
 
-
-/****************************************************************************/
-int rtp_packet_analyse(tap_rtp_stat_t *statinfo,
-                              packet_info *pinfo,
-                              const struct _rtp_info *rtpinfo)
-{
-       double current_time;
-       double current_jitter;
-       double current_diff;
-       guint32 clock_rate;
-
-       statinfo->flags = 0;
-       /* check payload type */
-       if (rtpinfo->info_payload_type == PT_CN
-               || rtpinfo->info_payload_type == PT_CN_OLD)
-               statinfo->flags |= STAT_FLAG_PT_CN;
-       if (statinfo->pt == PT_CN
-               || statinfo->pt == PT_CN_OLD)
-               statinfo->flags |= STAT_FLAG_FOLLOW_PT_CN;
-       if (rtpinfo->info_payload_type != statinfo->pt)
-               statinfo->flags |= STAT_FLAG_PT_CHANGE;
-       statinfo->pt = rtpinfo->info_payload_type;
-       /*
-        * XXX - should "get_clock_rate()" return 0 for unknown
-        * payload types, presumably meaning that we should
-        * just ignore this packet?
-        */
-       clock_rate = get_clock_rate(statinfo->pt);
-
-       /* store the current time and calculate the current jitter */
-       current_time = nstime_to_sec(&pinfo->fd->rel_ts);
-       current_diff = fabs (current_time - (statinfo->time) - ((double)(rtpinfo->info_timestamp)-(double)(statinfo->timestamp))/clock_rate);
-       current_jitter = statinfo->jitter + ( current_diff - statinfo->jitter)/16;
-       statinfo->delta = current_time-(statinfo->time);
-       statinfo->jitter = current_jitter;
-       statinfo->diff = current_diff;
-
-       /* calculate the BW in Kbps adding the IP+UDP header to the RTP -> 20bytes(IP)+8bytes(UDP) = 28bytes */
-       statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
-       statinfo->bw_history[statinfo->bw_index].time = current_time;
-       /* check if there are more than 1sec in the history buffer to calculate BW in bps. If so, remove those for the calculation */
-       while ((statinfo->bw_history[statinfo->bw_start_index].time+1)<current_time){
-               statinfo->total_bytes -= statinfo->bw_history[statinfo->bw_start_index].bytes;  
-               statinfo->bw_start_index++;
-               if (statinfo->bw_start_index == BUFF_BW) statinfo->bw_start_index=0;
-       };
-       statinfo->total_bytes += rtpinfo->info_data_len + 28;
-       statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
-       statinfo->bw_index++;
-       if (statinfo->bw_index == BUFF_BW) statinfo->bw_index = 0;      
-
-
-       /*  is this the first packet we got in this direction? */
-       if (statinfo->first_packet) {
-               statinfo->start_seq_nr = rtpinfo->info_seq_num;
-               statinfo->start_time = current_time;
-               statinfo->delta = 0;
-               statinfo->jitter = 0;
-               statinfo->diff = 0;
-               statinfo->flags |= STAT_FLAG_FIRST;
-               statinfo->first_packet = FALSE;
-       }
-       /* is it a packet with the mark bit set? */
-       if (rtpinfo->info_marker_set) {
-               if (rtpinfo->info_timestamp > statinfo->timestamp){
-                       statinfo->delta_timestamp = rtpinfo->info_timestamp - statinfo->timestamp;
-                       statinfo->flags |= STAT_FLAG_MARKER;
-               }
-               else{
-                       statinfo->flags |= STAT_FLAG_WRONG_TIMESTAMP;
-               }
-       }
-       /* is it a regular packet? */
-       if (!(statinfo->flags & STAT_FLAG_FIRST)
-               && !(statinfo->flags & STAT_FLAG_MARKER)
-               && !(statinfo->flags & STAT_FLAG_PT_CN)
-               && !(statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP)
-               && !(statinfo->flags & STAT_FLAG_FOLLOW_PT_CN)) {
-               /* include it in maximum delta calculation */
-               if (statinfo->delta > statinfo->max_delta) {
-                       statinfo->max_delta = statinfo->delta;
-                       statinfo->max_nr = pinfo->fd->num;
-               }
-               /* maximum and mean jitter calculation */
-               if (statinfo->jitter > statinfo->max_jitter) {
-                       statinfo->max_jitter = statinfo->jitter;
-               }
-               statinfo->mean_jitter = (statinfo->mean_jitter*statinfo->total_nr + current_diff) / (statinfo->total_nr+1);
-       }
-       /* regular payload change? (CN ignored) */
-       if (!(statinfo->flags & STAT_FLAG_FIRST)
-               && !(statinfo->flags & STAT_FLAG_PT_CN)) {
-               if ((statinfo->pt != statinfo->reg_pt)
-                       && (statinfo->reg_pt != PT_UNDEFINED)) {
-                       statinfo->flags |= STAT_FLAG_REG_PT_CHANGE;
-               }
-       }
-
-       /* set regular payload*/
-       if (!(statinfo->flags & STAT_FLAG_PT_CN)) {
-               statinfo->reg_pt = statinfo->pt;
-       }
-
-
-       /* When calculating expected rtp packets the seq number can wrap around
-       * so we have to count the number of cycles
-       * Variable cycles counts the wraps around in forwarding connection and
-       * under is flag that indicates where we are
-       *
-       * XXX how to determine number of cycles with all possible lost, late
-       * and duplicated packets without any doubt? It seems to me, that
-       * because of all possible combination of late, duplicated or lost
-       * packets, this can only be more or less good approximation
-       *
-       * There are some combinations (rare but theoretically possible),
-       * where below code won't work correctly - statistic may be wrong then.
-       */
-
-       /* so if the current sequence number is less than the start one
-       * we assume, that there is another cycle running */
-       if ((rtpinfo->info_seq_num < statinfo->start_seq_nr) && (statinfo->under == FALSE)){
-               statinfo->cycles++;
-               statinfo->under = TRUE;
-       }
-       /* what if the start seq nr was 0? Then the above condition will never
-       * be true, so we add another condition. XXX The problem would arise
-       * if one of the packets with seq nr 0 or 65535 would be lost or late */
-       else if ((rtpinfo->info_seq_num == 0) && (statinfo->stop_seq_nr == 65535) &&
-               (statinfo->under == FALSE)){
-               statinfo->cycles++;
-               statinfo->under = TRUE;
-       }
-       /* the whole round is over, so reset the flag */
-       else if ((rtpinfo->info_seq_num > statinfo->start_seq_nr) && (statinfo->under != FALSE)) {
-               statinfo->under = FALSE;
-       }
-
-       /* Since it is difficult to count lost, duplicate or late packets separately,
-       * we would like to know at least how many times the sequence number was not ok */
-
-       /* if the current seq number equals the last one or if we are here for
-       * the first time, then it is ok, we just store the current one as the last one */
-       if ( (statinfo->seq_num+1 == rtpinfo->info_seq_num) || (statinfo->flags & STAT_FLAG_FIRST) )
-               statinfo->seq_num = rtpinfo->info_seq_num;
-       /* if the first one is 65535. XXX same problem as above: if seq 65535 or 0 is lost... */
-       else if ( (statinfo->seq_num == 65535) && (rtpinfo->info_seq_num == 0) )
-               statinfo->seq_num = rtpinfo->info_seq_num;
-       /* lost packets */
-       else if (statinfo->seq_num+1 < rtpinfo->info_seq_num) {
-               statinfo->seq_num = rtpinfo->info_seq_num;
-               statinfo->sequence++;
-               statinfo->flags |= STAT_FLAG_WRONG_SEQ;
-       }
-       /* late or duplicated */
-       else if (statinfo->seq_num+1 > rtpinfo->info_seq_num) {
-               statinfo->sequence++;
-               statinfo->flags |= STAT_FLAG_WRONG_SEQ;
-       }
-       statinfo->time = current_time;
-       statinfo->timestamp = rtpinfo->info_timestamp;
-       statinfo->stop_seq_nr = rtpinfo->info_seq_num;
-       statinfo->total_nr++;
-
-       return 0;
-}
-
-
+/*
+Replaced by using the strings instead.
 static const GdkColor COLOR_DEFAULT = {0, 0xffff, 0xffff, 0xffff};
 static const GdkColor COLOR_ERROR = {0, 0xffff, 0xbfff, 0xbfff};
 static const GdkColor COLOR_WARNING = {0, 0xffff, 0xdfff, 0xbfff};
 static const GdkColor COLOR_CN = {0, 0xbfff, 0xbfff, 0xffff};
-
+static const GdkColor COLOR_FOREGROUND = {0, 0x0000, 0x0000, 0x0000};
+*/
 /****************************************************************************/
-/* adds statistics information from the packet to the clist */
-static int rtp_packet_add_info(GtkCList *clist,
+/* adds statistics information from the packet to the list */
+static int rtp_packet_add_info(GtkWidget *list, user_data_t * user_data,
        tap_rtp_stat_t *statinfo, packet_info *pinfo,
        const struct _rtp_info *rtpinfo)
 {
@@ -745,7 +521,7 @@ static int rtp_packet_add_info(GtkCList *clist,
        struct tm *tm_tmp;
        time_t then;
        gchar status[40];
-       GdkColor color = COLOR_DEFAULT;
+       gchar color_str[14];
        then = pinfo->fd->abs_ts.secs;
        msecs = (guint16)(pinfo->fd->abs_ts.nsecs/1000000);
        tm_tmp = localtime(&then);
@@ -758,25 +534,33 @@ static int rtp_packet_add_info(GtkCList *clist,
                tm_tmp->tm_sec,
                msecs);
 
+       /* Default to using black on white text if nothing below overrides it */
+       g_snprintf(color_str,sizeof(color_str),"#ffffffffffff");
+
        if (statinfo->pt == PT_CN) {
                g_snprintf(status,sizeof(status),"Comfort noise (PT=13, RFC 3389)");
-               color = COLOR_CN;
+               /* color = COLOR_CN; */
+               g_snprintf(color_str,sizeof(color_str),"#bfffbfffffff");
        }
        else if (statinfo->pt == PT_CN_OLD) {
                g_snprintf(status,sizeof(status),"Comfort noise (PT=19, reserved)");
-               color = COLOR_CN;
+               /* color = COLOR_CN; */
+               g_snprintf(color_str,sizeof(color_str),"#bfffbfffffff");
        }
        else if (statinfo->flags & STAT_FLAG_WRONG_SEQ) {
                g_snprintf(status,sizeof(status),"Wrong sequence nr.");
-               color = COLOR_ERROR;
+               /* color = COLOR_ERROR; */ 
+               g_snprintf(color_str,sizeof(color_str),"#ffffbfffbfff");
        }
        else if (statinfo->flags & STAT_FLAG_REG_PT_CHANGE) {
                g_snprintf(status,sizeof(status),"Payload changed to PT=%u", statinfo->pt);
-               color = COLOR_WARNING;
+               /* color = COLOR_WARNING; */
+               g_snprintf(color_str,sizeof(color_str),"#ffffdfffbfff");
        }
        else if (statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP) {
                g_snprintf(status,sizeof(status),"Incorrect timestamp");
-               color = COLOR_WARNING;
+               /* color = COLOR_WARNING; */
+               g_snprintf(color_str,sizeof(color_str),"#ffffdfffbfff");
        }
        else if ((statinfo->flags & STAT_FLAG_PT_CHANGE)
                &&  !(statinfo->flags & STAT_FLAG_FIRST)
@@ -784,50 +568,57 @@ static int rtp_packet_add_info(GtkCList *clist,
                &&  (statinfo->flags & STAT_FLAG_FOLLOW_PT_CN)
                &&  !(statinfo->flags & STAT_FLAG_MARKER)) {
                g_snprintf(status,sizeof(status),"Marker missing?");
-               color = COLOR_WARNING;
+               /* color = COLOR_WARNING; */
+               g_snprintf(color_str,sizeof(color_str),"#ffffdfffbfff");
        }
        else {
                if (statinfo->flags & STAT_FLAG_MARKER) {
-                       color = COLOR_WARNING;
+                       /* color = COLOR_WARNING; */
+                       g_snprintf(color_str,sizeof(color_str),"#ffffdfffbfff");
                }
                g_snprintf(status,sizeof(status),OK_TEXT);
        }
        /*  is this the first packet we got in this direction? */
        if (statinfo->flags & STAT_FLAG_FIRST) {
-               add_to_clist(clist,
+               add_to_list(list, user_data,
                        pinfo->fd->num, rtpinfo->info_seq_num,
                        0,
                        0,
+                       0,
                        statinfo->bandwidth,
                        status,
                        rtpinfo->info_marker_set,
                        timeStr, pinfo->fd->pkt_len,
-                       &color);
+                       color_str,
+                       statinfo->flags);
        }
        else {
-               add_to_clist(clist,
+               add_to_list(list, user_data,
                        pinfo->fd->num, rtpinfo->info_seq_num,
-                       statinfo->delta*1000,
-                       statinfo->jitter*1000,
+                       statinfo->delta,
+                       statinfo->jitter,
+                       statinfo->skew,
                        statinfo->bandwidth,
                        status,
                        rtpinfo->info_marker_set,
                        timeStr, pinfo->fd->pkt_len,
-                       &color);
+                       color_str,
+                       statinfo->flags);
        }
        return 0;
 }
 
-
+#define MAX_SILENCE_TICKS 1000000
 /****************************************************************************/
-static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo, 
+static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
                                    tap_rtp_stat_t *statinfo,
                                    packet_info *pinfo,
                                    const struct _rtp_info *rtpinfo)
 {
        guint i;
        const guint8 *data;
-       gint16 tmp;
+       guint8 tmp;
+       size_t nchars;
 
        /*  is this the first packet we got in this direction? */
        if (statinfo->flags & STAT_FLAG_FIRST) {
@@ -845,8 +636,9 @@ static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
                return 0;
 
        /* if the captured length and packet length aren't equal, we quit
-       * because there is some information missing */
-       if (pinfo->fd->pkt_len != pinfo->fd->cap_len) {
+       * if also the RTP dissector thinks there is some information missing */
+       if ((pinfo->fd->pkt_len != pinfo->fd->cap_len) &&
+           (!rtpinfo->info_all_data_present)) {
                saveinfo->saved = FALSE;
                saveinfo->error_type = TAP_RTP_WRONG_LENGTH;
                return 0;
@@ -864,21 +656,32 @@ static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
        /* do we need to insert some silence? */
        if ((rtpinfo->info_marker_set) &&
                !(statinfo->flags & STAT_FLAG_FIRST) &&
+               !(statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP) &&
                (statinfo->delta_timestamp > (rtpinfo->info_payload_len - rtpinfo->info_padding_count)) )  {
                /* the amount of silence should be the difference between
                * the last timestamp and the current one minus x
                * x should equal the amount of information in the last frame
                * XXX not done yet */
                for(i=0; i < (statinfo->delta_timestamp - rtpinfo->info_payload_len -
-                       rtpinfo->info_padding_count); i++) {
-                       tmp = (gint16 )ulaw2linear((unsigned char)(0x55));
-                       fwrite(&tmp, 2, 1, saveinfo->fp);
+                       rtpinfo->info_padding_count) && i < MAX_SILENCE_TICKS; i++) {
+                       switch (statinfo->reg_pt) {
+                       case PT_PCMU:
+                               tmp = SILENCE_PCMU;
+                               break;
+                       case PT_PCMA:
+                               tmp = SILENCE_PCMA;
+                               break;
+                       default:
+                               tmp = 0;
+                               break;
+                       }
+                       nchars=fwrite(&tmp, 1, 1, saveinfo->fp);
                        saveinfo->count++;
                }
                fflush(saveinfo->fp);
        }
 
-       
+
        if (rtpinfo->info_payload_type == PT_CN
                || rtpinfo->info_payload_type == PT_CN_OLD) {
        }
@@ -896,7 +699,7 @@ static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
                * plus the offset of the payload from the beginning
                * of the RTP data */
                data = rtpinfo->info_data + rtpinfo->info_payload_offset;
-               fwrite(data, sizeof(unsigned char), (rtpinfo->info_payload_len - rtpinfo->info_padding_count), saveinfo->fp);
+               nchars=fwrite(data, sizeof(unsigned char), (rtpinfo->info_payload_len - rtpinfo->info_padding_count), saveinfo->fp);
                saveinfo->count+=(rtpinfo->info_payload_len - rtpinfo->info_padding_count);
 
                fflush(saveinfo->fp);
@@ -912,14 +715,10 @@ static int rtp_packet_save_payload(tap_rtp_save_info_t *saveinfo,
 /* CALLBACKS */
 
 /****************************************************************************/
-/* XXX just copied from gtk/rpc_stat.c */
-void protect_thread_critical_region(void);
-void unprotect_thread_critical_region(void);
-
 
 /****************************************************************************/
 /* close the dialog window and remove the tap listener */
-static void on_destroy(GtkWidget *win _U_, user_data_t *user_data _U_)
+static void on_destroy(GtkWidget *win _U_, user_data_t *user_data)
 {
        /* remove tap listener */
        protect_thread_critical_region();
@@ -932,13 +731,14 @@ static void on_destroy(GtkWidget *win _U_, user_data_t *user_data _U_)
        if (user_data->reversed.saveinfo.fp != NULL)
                fclose(user_data->reversed.saveinfo.fp);
        /*XXX: test for error **/
-       remove(user_data->f_tempname);
-       remove(user_data->r_tempname);
+       ws_remove(user_data->f_tempname);
+       ws_remove(user_data->r_tempname);
 
+#if 0  /* XXX: GtkFileChooserDialog/gtk_dialog_run currently being used is effectively modal so this is not req'd */
        /* destroy save_voice_as window if open */
        if (user_data->dlg.save_voice_as_w != NULL)
                window_destroy(user_data->dlg.save_voice_as_w);
-
+#endif
        /* destroy graph window if open */
        if (user_data->dlg.dialog_graph.window != NULL)
                window_destroy(user_data->dlg.dialog_graph.window);
@@ -949,11 +749,9 @@ static void on_destroy(GtkWidget *win _U_, user_data_t *user_data _U_)
                window_destroy(user_data->dlg.graph_window);
 #endif
 
-       /* disable the "switch_page" signal in the dlg, otherwise will be called when the windows is destroy and cause an exeption using GTK1*/
-       gtk_signal_disconnect(GTK_OBJECT(user_data->dlg.notebook), user_data->dlg.notebook_signal_id);
+       /* disable the "switch_page" signal in the dlg, otherwise will be called when the windows is destroy and cause an exception using GTK1*/
+       g_signal_handler_disconnect(user_data->dlg.notebook, user_data->dlg.notebook_signal_id);
 
-       g_free(user_data->dlg.col_arrows_fwd);
-       g_free(user_data->dlg.col_arrows_rev);
        g_free(user_data);
 }
 
@@ -964,27 +762,25 @@ static void on_notebook_switch_page(GtkNotebook *notebook _U_,
                                     gint page_num _U_,
                                     user_data_t *user_data _U_)
 {
-       user_data->dlg.selected_clist =
-               (page_num==0) ? user_data->dlg.clist_fwd : user_data->dlg.clist_rev ;
-       user_data->dlg.selected_row = 0;
+       user_data->dlg.selected_list =
+               (page_num==0) ? user_data->dlg.list_fwd : user_data->dlg.list_rev ;
+
+       user_data->dlg.selected_list_row = 0;
 }
 
 /****************************************************************************/
-static void on_clist_select_row(GtkCList        *clist _U_,
-                                gint             row _U_,
-                                gint             column _U_,
-                                GdkEvent        *event _U_,
-                                user_data_t     *user_data _U_)
+
+static void on_list_select_row(GtkTreeSelection *selection, 
+                                                          user_data_t *user_data/*gpointer data */)
 {
-       user_data->dlg.selected_clist = clist;
-       user_data->dlg.selected_row = row;
+       user_data->dlg.selected_list_sel = selection;
 }
 
-
 #ifdef USE_CONVERSATION_GRAPH
+Note this will not work any more as clist is removed.
 /****************************************************************************/
 /* when the graph window gets destroyed */
-static void on_destroy_graph(GtkWidget *win _U_, user_data_t *user_data _U_)
+static void on_destroy_graph(GtkWidget *win _U_, user_data_t *user_data)
 {
        /* note that graph window has been destroyed */
        user_data->dlg.graph_window = NULL;
@@ -1005,7 +801,7 @@ static void graph_selection_callback(value_pair_t vp, user_data_t *user_data)
                                        GUINT_TO_POINTER(vp.fnumber));
                }
                if (row!=-1) {
-                       gtk_notebook_set_page(GTK_NOTEBOOK(user_data->dlg.notebook),
+                       gtk_notebook_set_current_page(GTK_NOTEBOOK(user_data->dlg.notebook),
                                (clist == GTK_CLIST(user_data->dlg.clist_fwd)) ? 0 : 1);
                        gtk_clist_select_row(clist, row, 0);
                        gtk_clist_moveto(clist, row, 0, 0.5, 0);
@@ -1020,7 +816,7 @@ static void on_graph_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        gchar title1[80];
        gchar title2[80];
        GList *list = NULL;
-       
+
        if (user_data->dlg.graph_window != NULL) {
                /* There's already a graph window; reactivate it. */
                reactivate_window(user_data->dlg.graph_window);
@@ -1041,14 +837,14 @@ static void on_graph_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        user_data->series_rev.color.blue = 0xffff;
        user_data->series_rev.yvalue = -0.5;
 
-       g_snprintf(title1, 80, "Forward: %s:%u to %s:%u (SSRC=%u)",
-               get_addr_name(&(user_data->ip_src_fwd)), 
+       g_snprintf(title1, sizeof(title1), "Forward: %s:%u to %s:%u (SSRC=0x%X)",
+               get_addr_name(&(user_data->ip_src_fwd)),
                user_data->port_src_fwd,
                get_addr_name(&(user_data->ip_dst_fwd)),
                user_data->port_dst_fwd,
                user_data->ssrc_fwd);
 
-       g_snprintf(title2, 80, "Reverse: %s:%u to %s:%u (SSRC=%u)",
+       g_snprintf(title2, sizeof(title2), "Reverse: %s:%u to %s:%u (SSRC=0x%X)",
                get_addr_name(&(user_data->ip_src_rev)),
                user_data->port_src_rev,
                get_addr_name(&(user_data->ip_dst_rev)),
@@ -1057,8 +853,8 @@ static void on_graph_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
 
        user_data->dlg.graph_window = show_conversation_graph(list, title1, title2,
                &graph_selection_callback, user_data);
-       SIGNAL_CONNECT(user_data->dlg.graph_window, "destroy",
-                       on_destroy_graph, user_data);
+       g_signal_connect(user_data->dlg.graph_window, "destroy",
+                       G_CALLBACK(on_destroy_graph), user_data);
 }
 #endif /*USE_CONVERSATION_GRAPH*/
 
@@ -1080,7 +876,7 @@ static void dialog_graph_set_title(user_data_t* user_data)
                        user_data->port_dst_rev);
 
        gtk_window_set_title(GTK_WINDOW(user_data->dlg.dialog_graph.window), title);
-       g_free(title);  
+       g_free(title);
 
 }
 
@@ -1105,28 +901,32 @@ static void dialog_graph_reset(user_data_t* user_data)
 
        /* create the color titles near the filter buttons */
        for(i=0;i<MAX_GRAPHS;i++){
-               /* it is forward */ 
+               /* it is forward */
                if (i<2){
-                               g_snprintf(user_data->dlg.dialog_graph.graph[i].title, 100, "%s: %s:%u to %s:%u (SSRC=%u)",
-                       graph_descr[i],
-                       get_addr_name(&(user_data->ip_src_fwd)),
-                       user_data->port_src_fwd,
-                       get_addr_name(&(user_data->ip_dst_fwd)),
-                       user_data->port_dst_fwd,
-                       user_data->ssrc_fwd);
+                       g_snprintf(user_data->dlg.dialog_graph.graph[i].title, 
+                                  sizeof(user_data->dlg.dialog_graph.graph[0].title),
+                                  "%s: %s:%u to %s:%u (SSRC=0x%X)",
+                                  graph_descr[i],
+                                  get_addr_name(&(user_data->ip_src_fwd)),
+                                  user_data->port_src_fwd,
+                                  get_addr_name(&(user_data->ip_dst_fwd)),
+                                  user_data->port_dst_fwd,
+                                  user_data->ssrc_fwd);
                /* it is reverse */
                } else {
-                       g_snprintf(user_data->dlg.dialog_graph.graph[i].title, 100, "%s: %s:%u to %s:%u (SSRC=%u)",
-                       graph_descr[i],
-                       get_addr_name(&(user_data->ip_src_rev)),
-                       user_data->port_src_rev,
-                       get_addr_name(&(user_data->ip_dst_rev)),
-                       user_data->port_dst_rev,
-                       user_data->ssrc_rev);
+                       g_snprintf(user_data->dlg.dialog_graph.graph[i].title, 
+                                  sizeof(user_data->dlg.dialog_graph.graph[0].title),
+                                  "%s: %s:%u to %s:%u (SSRC=0x%X)",
+                                  graph_descr[i],
+                                  get_addr_name(&(user_data->ip_src_rev)),
+                                  user_data->port_src_rev,
+                                  get_addr_name(&(user_data->ip_dst_rev)),
+                                  user_data->port_dst_rev,
+                                  user_data->ssrc_rev);
                }
        }
 
-       dialog_graph_set_title(user_data);      
+       dialog_graph_set_title(user_data);
 }
 
 /****************************************************************************/
@@ -1165,12 +965,8 @@ static void dialog_graph_draw(user_data_t* user_data)
         guint32 right_x_border;
         guint32 top_y_border;
         guint32 bottom_y_border;
-#if GTK_MAJOR_VERSION < 2
-        GdkFont *font;
-#else
         PangoLayout  *layout;
-#endif
-        guint32 label_width, label_height;
+        int label_width, label_height;
         guint32 draw_width, draw_height;
         char label_string[15];
 
@@ -1179,9 +975,6 @@ static void dialog_graph_draw(user_data_t* user_data)
         guint32 max_value;              /* max value of seen data */
         guint32 max_y;                  /* max value of the Y scale */
 
-#if GTK_MAJOR_VERSION <2
-        font = user_data->dlg.dialog_graph.draw_area->style->font;
-#endif
         if(!user_data->dlg.dialog_graph.needs_redraw){
                 return;
         }
@@ -1224,7 +1017,7 @@ static void dialog_graph_draw(user_data_t* user_data)
                         }
                 }
         }
-       
+
         /*
          * Clear out old plot
          */
@@ -1257,14 +1050,9 @@ static void dialog_graph_draw(user_data_t* user_data)
          * on the width of the text labels. For simplicity we assume that the
          * top y scale label will be the widest one
          */
-         print_time_scale_string(label_string, 15, max_y);
-#if GTK_MAJOR_VERSION < 2
-        label_width=gdk_string_width(font, label_string);
-        label_height=gdk_string_height(font, label_string);
-#else
+       print_time_scale_string(label_string, sizeof(label_string), max_y);
         layout = gtk_widget_create_pango_layout(user_data->dlg.dialog_graph.draw_area, label_string);
         pango_layout_get_pixel_size(layout, &label_width, &label_height);
-#endif
         left_x_border=10;
         right_x_border=label_width+20;
         top_y_border=10;
@@ -1303,16 +1091,7 @@ static void dialog_graph_draw(user_data_t* user_data)
                         user_data->dlg.dialog_graph.pixmap_height-bottom_y_border-draw_height*i/10);
                 /* draw the labels */
                 if(i==0){
-                        print_time_scale_string(label_string, 15, (max_y*i/10));
-#if GTK_MAJOR_VERSION < 2
-                        lwidth=gdk_string_width(font, label_string);
-                        gdk_draw_string(user_data->dlg.dialog_graph.pixmap,
-                                        font,
-                                        user_data->dlg.dialog_graph.draw_area->style->black_gc,
-                                        user_data->dlg.dialog_graph.pixmap_width-right_x_border+15+label_width-lwidth,
-                                        user_data->dlg.dialog_graph.pixmap_height-bottom_y_border-draw_height*i/10+label_height/2,
-                                        label_string);
-#else
+                        print_time_scale_string(label_string, sizeof(label_string), (max_y*i/10));
                         pango_layout_set_text(layout, label_string, -1);
                         pango_layout_get_pixel_size(layout, &lwidth, NULL);
                         gdk_draw_layout(user_data->dlg.dialog_graph.pixmap,
@@ -1320,19 +1099,9 @@ static void dialog_graph_draw(user_data_t* user_data)
                                         user_data->dlg.dialog_graph.pixmap_width-right_x_border+15+label_width-lwidth,
                                         user_data->dlg.dialog_graph.pixmap_height-bottom_y_border-draw_height*i/10-label_height/2,
                                         layout);
-#endif
                 }
                 if(i==5){
-                        print_time_scale_string(label_string, 15, (max_y*i/10));
-#if GTK_MAJOR_VERSION < 2
-                        lwidth=gdk_string_width(font, label_string);
-                        gdk_draw_string(user_data->dlg.dialog_graph.pixmap,
-                                        font,
-                                        user_data->dlg.dialog_graph.draw_area->style->black_gc,
-                                        user_data->dlg.dialog_graph.pixmap_width-right_x_border+15+label_width-lwidth,
-                                        user_data->dlg.dialog_graph.pixmap_height-bottom_y_border-draw_height*i/10+label_height/2,
-                                        label_string);
-#else
+                        print_time_scale_string(label_string, sizeof(label_string), (max_y*i/10));
                         pango_layout_set_text(layout, label_string, -1);
                         pango_layout_get_pixel_size(layout, &lwidth, NULL);
                         gdk_draw_layout(user_data->dlg.dialog_graph.pixmap,
@@ -1340,19 +1109,9 @@ static void dialog_graph_draw(user_data_t* user_data)
                                         user_data->dlg.dialog_graph.pixmap_width-right_x_border+15+label_width-lwidth,
                                         user_data->dlg.dialog_graph.pixmap_height-bottom_y_border-draw_height*i/10-label_height/2,
                                         layout);
-#endif
                 }
                 if(i==10){
-                        print_time_scale_string(label_string, 15, (max_y*i/10));
-#if GTK_MAJOR_VERSION < 2
-                        lwidth=gdk_string_width(font, label_string);
-                        gdk_draw_string(user_data->dlg.dialog_graph.pixmap,
-                                        font,
-                                        user_data->dlg.dialog_graph.draw_area->style->black_gc,
-                                        user_data->dlg.dialog_graph.pixmap_width-right_x_border+15+label_width-lwidth,
-                                        user_data->dlg.dialog_graph.pixmap_height-bottom_y_border-draw_height*i/10+label_height/2,
-                                        label_string);
-#else
+                        print_time_scale_string(label_string, sizeof(label_string), (max_y*i/10));
                         pango_layout_set_text(layout, label_string, -1);
                         pango_layout_get_pixel_size(layout, &lwidth, NULL);
                         gdk_draw_layout(user_data->dlg.dialog_graph.pixmap,
@@ -1360,7 +1119,6 @@ static void dialog_graph_draw(user_data_t* user_data)
                                         user_data->dlg.dialog_graph.pixmap_width-right_x_border+15+label_width-lwidth,
                                         user_data->dlg.dialog_graph.pixmap_height-bottom_y_border-draw_height*i/10-label_height/2,
                                         layout);
-#endif
                 }
         }
 
@@ -1426,25 +1184,14 @@ static void dialog_graph_draw(user_data_t* user_data)
                 if(xlen==17){
                         int lwidth;
                         if(user_data->dlg.dialog_graph.interval>=1000){
-                                g_snprintf(label_string, 15, "%ds", current_interval/1000);
+                                g_snprintf(label_string, sizeof(label_string), "%ds", current_interval/1000);
                         } else if(user_data->dlg.dialog_graph.interval>=100){
-                                g_snprintf(label_string, 15, "%d.%1ds", current_interval/1000,(current_interval/100)%10)
-;
+                                g_snprintf(label_string, sizeof(label_string), "%d.%1ds", current_interval/1000,(current_interval/100)%10);
                         } else if(user_data->dlg.dialog_graph.interval>=10){
-                                g_snprintf(label_string, 15, "%d.%2ds", current_interval/1000,(current_interval/10)%100)
-;
+                                g_snprintf(label_string, sizeof(label_string), "%d.%2ds", current_interval/1000,(current_interval/10)%100);
                         } else {
-                                g_snprintf(label_string, 15, "%d.%3ds", current_interval/1000,current_interval%1000);
+                                g_snprintf(label_string, sizeof(label_string), "%d.%3ds", current_interval/1000,current_interval%1000);
                         }
-#if GTK_MAJOR_VERSION < 2
-                        lwidth=gdk_string_width(font, label_string);
-                        gdk_draw_string(user_data->dlg.dialog_graph.pixmap,
-                                        font,
-                                        user_data->dlg.dialog_graph.draw_area->style->black_gc,
-                                        x-1-user_data->dlg.dialog_graph.pixels_per_tick/2-lwidth/2,
-                                        user_data->dlg.dialog_graph.pixmap_height-bottom_y_border+20+label_height,
-                                        label_string);
-#else
                         pango_layout_set_text(layout, label_string, -1);
                         pango_layout_get_pixel_size(layout, &lwidth, NULL);
                         gdk_draw_layout(user_data->dlg.dialog_graph.pixmap,
@@ -1452,7 +1199,6 @@ static void dialog_graph_draw(user_data_t* user_data)
                                         x-1-user_data->dlg.dialog_graph.pixels_per_tick/2-lwidth/2,
                                         user_data->dlg.dialog_graph.pixmap_height-bottom_y_border+20,
                                         layout);
-#endif
                 }
 
         }
@@ -1466,16 +1212,7 @@ static void dialog_graph_draw(user_data_t* user_data)
          * Draw "x" for Sequence Errors and "m" for Marks
          */
        /* Draw the labels Fwd and Rev */
-       strcpy(label_string,"<-Fwd");
-#if GTK_MAJOR_VERSION < 2
-       lwidth=gdk_string_width(font, label_string);
-       gdk_draw_string(user_data->dlg.dialog_graph.pixmap,
-               font,
-               user_data->dlg.dialog_graph.draw_area->style->black_gc,
-               user_data->dlg.dialog_graph.pixmap_width-right_x_border+33-lwidth,
-               user_data->dlg.dialog_graph.pixmap_height-bottom_y_border+3+label_height,
-               label_string);
-#else
+       g_strlcpy(label_string,"<-Fwd",sizeof(label_string));
        pango_layout_set_text(layout, label_string, -1);
        pango_layout_get_pixel_size(layout, &lwidth, NULL);
        gdk_draw_layout(user_data->dlg.dialog_graph.pixmap,
@@ -1483,17 +1220,7 @@ static void dialog_graph_draw(user_data_t* user_data)
                user_data->dlg.dialog_graph.pixmap_width-right_x_border+33-lwidth,
                user_data->dlg.dialog_graph.pixmap_height-bottom_y_border+3,
                layout);
-#endif
-        strcpy(label_string,"<-Rev");
-#if GTK_MAJOR_VERSION < 2
-        lwidth=gdk_string_width(font, label_string);
-        gdk_draw_string(user_data->dlg.dialog_graph.pixmap,
-                font,
-                user_data->dlg.dialog_graph.draw_area->style->black_gc,
-                user_data->dlg.dialog_graph.pixmap_width-right_x_border+33-lwidth,
-                user_data->dlg.dialog_graph.pixmap_height-bottom_y_border+3+9+label_height,
-                label_string);
-#else
+        g_strlcpy(label_string,"<-Rev",sizeof(label_string));
         pango_layout_set_text(layout, label_string, -1);
         pango_layout_get_pixel_size(layout, &lwidth, NULL);
         gdk_draw_layout(user_data->dlg.dialog_graph.pixmap,
@@ -1501,9 +1228,8 @@ static void dialog_graph_draw(user_data_t* user_data)
                 user_data->dlg.dialog_graph.pixmap_width-right_x_border+33-lwidth,
                 user_data->dlg.dialog_graph.pixmap_height-bottom_y_border+3+9,
                 layout);
-#endif
 
-       /* Draw the marks */    
+       /* Draw the marks */
        for(i=MAX_GRAPHS-1;i>=0;i--){
                guint32 interval;
                guint32 x_pos, prev_x_pos;
@@ -1521,20 +1247,11 @@ static void dialog_graph_draw(user_data_t* user_data)
                        if(user_data->dlg.dialog_graph.graph[i].items[interval/user_data->dlg.dialog_graph.interval].flags & (STAT_FLAG_WRONG_SEQ|STAT_FLAG_MARKER)){
                                int lwidth;
                                if (user_data->dlg.dialog_graph.graph[i].items[interval/user_data->dlg.dialog_graph.interval].flags & STAT_FLAG_WRONG_SEQ){
-                                       strcpy(label_string,"x");
+                                       g_strlcpy(label_string,"x",sizeof(label_string));
                                } else {
-                                       strcpy(label_string,"m");
+                                       g_strlcpy(label_string,"m",sizeof(label_string));
                                }
-                                       
-#if GTK_MAJOR_VERSION < 2
-                                lwidth=gdk_string_width(font, label_string);
-                                gdk_draw_string(user_data->dlg.dialog_graph.pixmap,
-                                        font,
-                                        user_data->dlg.dialog_graph.draw_area->style->black_gc,
-                                        x_pos-1-lwidth/2,
-                                        user_data->dlg.dialog_graph.pixmap_height-bottom_y_border+3+7*(i/2)+label_height,
-                                        label_string);
-#else                          
+
                                pango_layout_set_text(layout, label_string, -1);
                                 pango_layout_get_pixel_size(layout, &lwidth, NULL);
                                 gdk_draw_layout(user_data->dlg.dialog_graph.pixmap,
@@ -1542,17 +1259,13 @@ static void dialog_graph_draw(user_data_t* user_data)
                                         x_pos-1-lwidth/2,
                                         user_data->dlg.dialog_graph.pixmap_height-bottom_y_border+3+7*(i/2),
                                         layout);
-#endif
                         }
 
                         prev_x_pos=x_pos;
                 }
         }
 
-#if GTK_MAJOR_VERSION >= 2
         g_object_unref(G_OBJECT(layout));
-#endif
-
 
         /*
          * Loop over all graphs and draw them
@@ -1562,11 +1275,11 @@ static void dialog_graph_draw(user_data_t* user_data)
                guint32 x_pos, y_pos, prev_x_pos, prev_y_pos;
                if (!user_data->dlg.dialog_graph.graph[i].display){
                         continue;
-                }      
+                }
                /* initialize prev x/y to the low left corner of the graph */
                prev_x_pos=draw_width-1-user_data->dlg.dialog_graph.pixels_per_tick*((last_interval-first_interval)/user_data->dlg.dialog_graph.interval+1)+left_x_border;
                prev_y_pos=draw_height-1+top_y_border;
-               
+
                for(interval=first_interval+user_data->dlg.dialog_graph.interval;interval<=last_interval;interval+=user_data->dlg.dialog_graph.interval){
                        guint32 val;
                        x_pos=draw_width-1-user_data->dlg.dialog_graph.pixels_per_tick*((last_interval-interval)/user_data->dlg.dialog_graph.interval+1)+left_x_border;
@@ -1585,7 +1298,7 @@ static void dialog_graph_draw(user_data_t* user_data)
                                 prev_x_pos=x_pos;
                                 continue;
                         }
-               
+
                         if(val){
                                gdk_draw_line(user_data->dlg.dialog_graph.pixmap, user_data->dlg.dialog_graph.graph[i].gc,
                                 x_pos, draw_height-1+top_y_border,
@@ -1625,18 +1338,13 @@ static void dialog_graph_draw(user_data_t* user_data)
 static void dialog_graph_redraw(user_data_t* user_data)
 {
         user_data->dlg.dialog_graph.needs_redraw=TRUE;
-        dialog_graph_draw(user_data); 
+        dialog_graph_draw(user_data);
 }
 
 /****************************************************************************/
-static gint quit(GtkWidget *widget, GdkEventExpose *event _U_)
+static void quit(GtkWidget *widget _U_, user_data_t *user_data)
 {
-        user_data_t *user_data;
-
-        user_data=(user_data_t *)OBJECT_GET_DATA(widget, "user_data_t");
-
        user_data->dlg.dialog_graph.window = NULL;
-        return TRUE;
 }
 
 /****************************************************************************/
@@ -1644,10 +1352,10 @@ static gint expose_event(GtkWidget *widget, GdkEventExpose *event)
 {
        user_data_t *user_data;
 
-       user_data=(user_data_t *)OBJECT_GET_DATA(widget, "user_data_t");
-        if(!user_data){
-                exit(10);
-        }
+       user_data=(user_data_t *)g_object_get_data(G_OBJECT(widget), "user_data_t");
+    if(!user_data){
+               exit(10);
+    }
 
 
         gdk_draw_pixmap(widget->window,
@@ -1666,7 +1374,7 @@ static gint configure_event(GtkWidget *widget, GdkEventConfigure *event _U_)
         user_data_t *user_data;
        int i;
 
-        user_data=(user_data_t *)OBJECT_GET_DATA(widget, "user_data_t");
+        user_data=(user_data_t *)g_object_get_data(G_OBJECT(widget), "user_data_t");
 
         if(!user_data){
                 exit(10);
@@ -1694,16 +1402,7 @@ static gint configure_event(GtkWidget *widget, GdkEventConfigure *event _U_)
         /* set up the colors and the GC structs for this pixmap */
        for(i=0;i<MAX_GRAPHS;i++){
                user_data->dlg.dialog_graph.graph[i].gc=gdk_gc_new(user_data->dlg.dialog_graph.pixmap);
-#if GTK_MAJOR_VERSION < 2
-                colormap = gtk_widget_get_colormap (widget);
-                if (!gdk_color_alloc (colormap, &user_data->dlg.dialog_graph.graph[i].color)){
-                        g_warning ("Couldn't allocate color");
-                }
-
-                gdk_gc_set_foreground(user_data->dlg.dialog_graph.graph[i].gc, &user_data->dlg.dialog_graph.graph[i].color);
-#else
                 gdk_gc_set_rgb_fg_color(user_data->dlg.dialog_graph.graph[i].gc, &user_data->dlg.dialog_graph.graph[i].color);
-#endif
        }
 
        dialog_graph_redraw(user_data);
@@ -1735,14 +1434,14 @@ static gint scrollbar_changed(GtkWidget *widget _U_, gpointer data)
 static void create_draw_area(user_data_t* user_data, GtkWidget *box)
 {
         user_data->dlg.dialog_graph.draw_area=gtk_drawing_area_new();
-        SIGNAL_CONNECT(user_data->dlg.dialog_graph.draw_area, "destroy", quit, user_data);
-        OBJECT_SET_DATA(user_data->dlg.dialog_graph.draw_area, "user_data_t", user_data);
+        g_signal_connect(user_data->dlg.dialog_graph.draw_area, "destroy", G_CALLBACK(quit), user_data);
+        g_object_set_data(G_OBJECT(user_data->dlg.dialog_graph.draw_area), "user_data_t", user_data);
 
-        WIDGET_SET_SIZE(user_data->dlg.dialog_graph.draw_area, user_data->dlg.dialog_graph.pixmap_width, user_data->dlg.dialog_graph.pixmap_height);
+        gtk_widget_set_size_request(user_data->dlg.dialog_graph.draw_area, user_data->dlg.dialog_graph.pixmap_width, user_data->dlg.dialog_graph.pixmap_height);
 
         /* signals needed to handle backing pixmap */
-        SIGNAL_CONNECT(user_data->dlg.dialog_graph.draw_area, "expose_event", expose_event, NULL);
-        SIGNAL_CONNECT(user_data->dlg.dialog_graph.draw_area, "configure_event", configure_event, user_data);
+        g_signal_connect(user_data->dlg.dialog_graph.draw_area, "expose_event", G_CALLBACK(expose_event), NULL);
+        g_signal_connect(user_data->dlg.dialog_graph.draw_area, "configure_event", G_CALLBACK(configure_event), user_data);
 
         gtk_widget_show(user_data->dlg.dialog_graph.draw_area);
         gtk_box_pack_start(GTK_BOX(box), user_data->dlg.dialog_graph.draw_area, TRUE, TRUE, 0);
@@ -1752,7 +1451,7 @@ static void create_draw_area(user_data_t* user_data, GtkWidget *box)
         user_data->dlg.dialog_graph.scrollbar=gtk_hscrollbar_new(user_data->dlg.dialog_graph.scrollbar_adjustment);
         gtk_widget_show(user_data->dlg.dialog_graph.scrollbar);
         gtk_box_pack_start(GTK_BOX(box), user_data->dlg.dialog_graph.scrollbar, FALSE, FALSE, 0);
-        SIGNAL_CONNECT(user_data->dlg.dialog_graph.scrollbar_adjustment, "value_changed", scrollbar_changed, user_data);
+        g_signal_connect(user_data->dlg.dialog_graph.scrollbar_adjustment, "value_changed", G_CALLBACK(scrollbar_changed), user_data);
 }
 
 /****************************************************************************/
@@ -1770,12 +1469,12 @@ static gint filter_callback(GtkWidget *widget _U_, dialog_graph_graph_t *dgg)
 {
         /* this graph is not active, just update display and redraw */
         if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dgg->display_button))){
-                disable_graph(dgg); 
+                disable_graph(dgg);
                 dialog_graph_redraw(dgg->ud);
                return 0;
         }
 
-       enable_graph(dgg);
+               enable_graph(dgg);
         cf_retap_packets(&cfile, FALSE);
         dialog_graph_redraw(dgg->ud);
 
@@ -1794,39 +1493,22 @@ static void create_filter_box(dialog_graph_graph_t *dgg, GtkWidget *box, int num
         gtk_box_set_child_packing(GTK_BOX(box), hbox, FALSE, FALSE, 0, GTK_PACK_START);
         gtk_widget_show(hbox);
 
-       g_snprintf(str, 256, "Graph %d", num);
+       g_snprintf(str, sizeof(str), "Graph %d", num);
        dgg->display_button=gtk_toggle_button_new_with_label(str);
         gtk_box_pack_start(GTK_BOX(hbox), dgg->display_button, FALSE, FALSE, 0);
         gtk_widget_show(dgg->display_button);
         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dgg->display_button), dgg->display);
-        SIGNAL_CONNECT(dgg->display_button, "toggled", filter_callback, dgg);
+        g_signal_connect(dgg->display_button, "toggled", G_CALLBACK(filter_callback), dgg);
 
        label=gtk_label_new(dgg->title);
         gtk_widget_show(label);
         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
-#if GTK_MAJOR_VERSION < 2
-    /* setting the color of the display button doesn't work */
-        rc_style = gtk_rc_style_new ();
-        rc_style->fg[GTK_STATE_NORMAL] = dgg->color;
-        rc_style->color_flags[GTK_STATE_NORMAL] |= GTK_RC_FG;
-        rc_style->fg[GTK_STATE_ACTIVE] = dgg->color;
-        rc_style->color_flags[GTK_STATE_ACTIVE] |= GTK_RC_FG;
-        rc_style->fg[GTK_STATE_PRELIGHT] = dgg->color;
-        rc_style->color_flags[GTK_STATE_PRELIGHT] |= GTK_RC_FG;
-        rc_style->fg[GTK_STATE_SELECTED] = dgg->color;
-        rc_style->color_flags[GTK_STATE_SELECTED] |= GTK_RC_FG;
-        rc_style->fg[GTK_STATE_INSENSITIVE] = dgg->color;
-        rc_style->color_flags[GTK_STATE_INSENSITIVE] |= GTK_RC_FG;
-        gtk_widget_modify_style (label, rc_style);
-        gtk_rc_style_unref (rc_style);
-#else
         gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &dgg->color);
         gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, &dgg->color);
         gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, &dgg->color);
         gtk_widget_modify_fg(label, GTK_STATE_SELECTED, &dgg->color);
         gtk_widget_modify_fg(label, GTK_STATE_INSENSITIVE, &dgg->color);
-#endif
 
         return;
 }
@@ -1845,7 +1527,7 @@ static void create_filter_area(user_data_t* user_data, GtkWidget *box)
 
         vbox=gtk_vbox_new(FALSE, 1);
         gtk_container_add(GTK_CONTAINER(frame), vbox);
-       gtk_container_border_width(GTK_CONTAINER(vbox), 3);
+       gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
         gtk_box_set_child_packing(GTK_BOX(box), vbox, FALSE, FALSE, 0, GTK_PACK_START);
         gtk_widget_show(vbox);
 
@@ -1865,9 +1547,9 @@ static void yscale_select(GtkWidget *item, gpointer key)
 {
         int val;
        user_data_t *user_data;
-        
+
         user_data=(user_data_t *)key;
-        val=(int)OBJECT_GET_DATA(item, "yscale_max");
+        val=(long)g_object_get_data(G_OBJECT(item), "yscale_max");
 
         user_data->dlg.dialog_graph.max_y_units=val;
         dialog_graph_redraw(user_data);
@@ -1880,7 +1562,7 @@ static void pixels_per_tick_select(GtkWidget *item, gpointer key)
         user_data_t *user_data;
 
         user_data=(user_data_t *)key;
-        val=(int)OBJECT_GET_DATA(item, "pixels_per_tick");
+        val=(long)g_object_get_data(G_OBJECT(item), "pixels_per_tick");
         user_data->dlg.dialog_graph.pixels_per_tick=val;
         dialog_graph_redraw(user_data);
 }
@@ -1892,7 +1574,7 @@ static void tick_interval_select(GtkWidget *item, gpointer key)
         user_data_t *user_data;
 
         user_data=(user_data_t *)key;
-        val=(int)OBJECT_GET_DATA(item, "tick_interval");
+        val=(long)g_object_get_data(G_OBJECT(item), "tick_interval");
 
         user_data->dlg.dialog_graph.interval=val;
         cf_retap_packets(&cfile, FALSE);
@@ -1908,16 +1590,16 @@ static void create_yscale_max_menu_items(user_data_t* user_data, GtkWidget *menu
 
         for(i=0;i<MAX_YSCALE;i++){
                 if(yscale_max[i]==AUTO_MAX_YSCALE){
-                        strcpy(str,"Auto");
+                       g_strlcpy(str,"Auto",sizeof(str));
                 } else {
-                        g_snprintf(str, 15, "%u ms", yscale_max[i]/1000);
+                        g_snprintf(str, sizeof(str), "%u ms", yscale_max[i]/1000);
                 }
                 menu_item=gtk_menu_item_new_with_label(str);
-                OBJECT_SET_DATA(menu_item, "yscale_max",
+                g_object_set_data(G_OBJECT(menu_item), "yscale_max",
                                 GUINT_TO_POINTER(yscale_max[i]));
-                SIGNAL_CONNECT(menu_item, "activate", yscale_select, user_data);
+                g_signal_connect(menu_item, "activate", G_CALLBACK(yscale_select), user_data);
                 gtk_widget_show(menu_item);
-                gtk_menu_append(GTK_MENU(menu), menu_item);
+                gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
         }
         return;
 }
@@ -1930,14 +1612,14 @@ static void create_pixels_per_tick_menu_items(user_data_t* user_data, GtkWidget
         int i;
 
         for(i=0;i<MAX_PIXELS_PER_TICK;i++){
-                g_snprintf(str, 5, "%u", pixels_per_tick[i]);
+                g_snprintf(str, sizeof(str), "%u", pixels_per_tick[i]);
                 menu_item=gtk_menu_item_new_with_label(str);
 
-                OBJECT_SET_DATA(menu_item, "pixels_per_tick",
+                g_object_set_data(G_OBJECT(menu_item), "pixels_per_tick",
                                 GUINT_TO_POINTER(pixels_per_tick[i]));
-                SIGNAL_CONNECT(menu_item, "activate", pixels_per_tick_select, user_data);
+                g_signal_connect(menu_item, "activate", G_CALLBACK(pixels_per_tick_select), user_data);
                 gtk_widget_show(menu_item);
-                gtk_menu_append(GTK_MENU(menu), menu_item);
+                gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
         }
         gtk_menu_set_active(GTK_MENU(menu), DEFAULT_PIXELS_PER_TICK);
         return;
@@ -1953,21 +1635,21 @@ static void create_tick_interval_menu_items(user_data_t* user_data, GtkWidget *m
 
         for(i=0;i<MAX_TICK_VALUES;i++){
                 if(tick_interval_values[i]>=1000){
-                        g_snprintf(str, 15, "%u sec", tick_interval_values[i]/1000);
+                        g_snprintf(str, sizeof(str), "%u sec", tick_interval_values[i]/1000);
                 } else if(tick_interval_values[i]>=100){
-                        g_snprintf(str, 15, "0.%1u sec", (tick_interval_values[i]/100)%10);
+                        g_snprintf(str, sizeof(str), "0.%1u sec", (tick_interval_values[i]/100)%10);
                 } else if(tick_interval_values[i]>=10){
-                        g_snprintf(str, 15, "0.%02u sec", (tick_interval_values[i]/10)%10);
+                        g_snprintf(str, sizeof(str), "0.%02u sec", (tick_interval_values[i]/10)%10);
                 } else {
-                        g_snprintf(str, 15, "0.%03u sec", (tick_interval_values[i])%10);
+                        g_snprintf(str, sizeof(str), "0.%03u sec", (tick_interval_values[i])%10);
                 }
 
                 menu_item=gtk_menu_item_new_with_label(str);
-                OBJECT_SET_DATA(menu_item, "tick_interval",
+                g_object_set_data(G_OBJECT(menu_item), "tick_interval",
                                 GUINT_TO_POINTER(tick_interval_values[i]));
-                SIGNAL_CONNECT(menu_item, "activate", tick_interval_select, (gpointer)user_data);
+                g_signal_connect(menu_item, "activate", G_CALLBACK(tick_interval_select), (gpointer)user_data);
                 gtk_widget_show(menu_item);
-                gtk_menu_append(GTK_MENU(menu), menu_item);
+                gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
         }
         gtk_menu_set_active(GTK_MENU(menu), DEFAULT_TICK_VALUE);
         return;
@@ -2015,7 +1697,7 @@ static void create_ctrl_area(user_data_t* user_data, GtkWidget *box)
 
         vbox=gtk_vbox_new(FALSE, 0);
         gtk_container_add(GTK_CONTAINER(frame), vbox);
-       gtk_container_border_width(GTK_CONTAINER(vbox), 3);
+       gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
         gtk_box_set_child_packing(GTK_BOX(box), vbox, FALSE, FALSE, 0, GTK_PACK_END);
         gtk_widget_show(vbox);
 
@@ -2028,7 +1710,7 @@ static void create_ctrl_area(user_data_t* user_data, GtkWidget *box)
 
         vbox=gtk_vbox_new(FALSE, 0);
         gtk_container_add(GTK_CONTAINER(frame), vbox);
-       gtk_container_border_width(GTK_CONTAINER(vbox), 3);
+       gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
         gtk_box_set_child_packing(GTK_BOX(box), vbox, FALSE, FALSE, 0, GTK_PACK_END);
         gtk_widget_show(vbox);
 
@@ -2045,7 +1727,7 @@ static void dialog_graph_init_window(user_data_t* user_data)
        GtkWidget *bt_close;
 
         /* create the main window */
-        user_data->dlg.dialog_graph.window=window_new(GTK_WINDOW_TOPLEVEL, "I/O Graphs");
+        user_data->dlg.dialog_graph.window=dlg_window_new("I/O Graphs");   /* transient_for top_level */
 
         vbox=gtk_vbox_new(FALSE, 0);
         gtk_container_add(GTK_CONTAINER(user_data->dlg.dialog_graph.window), vbox);
@@ -2055,7 +1737,7 @@ static void dialog_graph_init_window(user_data_t* user_data)
 
         hbox=gtk_hbox_new(FALSE, 3);
         gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
-       gtk_container_border_width(GTK_CONTAINER(hbox), 3);
+       gtk_container_set_border_width(GTK_CONTAINER(hbox), 3);
         gtk_box_set_child_packing(GTK_BOX(vbox), hbox, FALSE, FALSE, 0, GTK_PACK_START);
         gtk_widget_show(hbox);
 
@@ -2068,10 +1750,10 @@ static void dialog_graph_init_window(user_data_t* user_data)
         gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
     gtk_widget_show(hbox);
 
-    bt_close = OBJECT_GET_DATA(hbox, GTK_STOCK_CLOSE);
+    bt_close = g_object_get_data(G_OBJECT(hbox), GTK_STOCK_CLOSE);
     window_set_cancel_button(user_data->dlg.dialog_graph.window, bt_close, window_cancel_button_cb);
 
-    SIGNAL_CONNECT(user_data->dlg.dialog_graph.window, "delete_event", window_delete_event_cb, NULL);
+    g_signal_connect(user_data->dlg.dialog_graph.window, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
 
     gtk_widget_show(user_data->dlg.dialog_graph.window);
     window_present(user_data->dlg.dialog_graph.window);
@@ -2080,7 +1762,7 @@ static void dialog_graph_init_window(user_data_t* user_data)
 
 
 /****************************************************************************/
-static void on_graph_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
+static void on_graph_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data)
 {
         if (user_data->dlg.dialog_graph.window != NULL) {
                 /* There's already a graph window; reactivate it. */
@@ -2088,31 +1770,39 @@ static void on_graph_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
                 return;
         }
 
-       dialog_graph_init_window(user_data);    
+       dialog_graph_init_window(user_data);
 
 }
 
 /****************************************************************************/
-static void on_goto_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
+
+static void on_goto_bt_clicked_lst(GtkWidget *bt _U_, user_data_t *user_data _U_)
 {
+       GtkTreeIter iter;
+       GtkTreeModel *model;
+       GtkTreeSelection *selection;
        guint fnumber;
 
-       if (user_data->dlg.selected_clist!=NULL) {
-               fnumber = GPOINTER_TO_UINT(gtk_clist_get_row_data(
-                       GTK_CLIST(user_data->dlg.selected_clist), user_data->dlg.selected_row) );
+       selection = user_data->dlg.selected_list_sel;
+
+       if (selection==NULL)
+               return;
+       
+       if (gtk_tree_selection_get_selected (selection, &model, &iter)){
+               gtk_tree_model_get (model, &iter, PACKET_COLUMN, &fnumber, -1);
                cf_goto_frame(&cfile, fnumber);
        }
-}
 
+}
 
 static void draw_stat(user_data_t *user_data);
 
 /****************************************************************************/
 /* re-dissects all packets */
-static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
+static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data)
 {
        GString *error_string;
-       
+
        /* remove tap listener */
        protect_thread_critical_region();
        remove_tap_listener(user_data);
@@ -2122,7 +1812,7 @@ static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        error_string = register_tap_listener("rtp", user_data, NULL,
                rtp_reset, rtp_packet, rtp_draw);
        if (error_string != NULL) {
-               simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
+               simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
                        g_string_free(error_string, TRUE);
                return;
        }
@@ -2133,88 +1823,113 @@ static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        /* draw statistics info */
        draw_stat(user_data);
 
-       gtk_clist_sort(user_data->dlg.clist_fwd);
-       gtk_clist_sort(user_data->dlg.clist_rev);
 }
 
-/****************************************************************************/
-static void on_next_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
+static void on_next_bt_clicked_list(GtkWidget *bt _U_, user_data_t *user_data _U_)
 {
-       GtkCList *clist;
+       GtkTreeIter iter;
+       GtkTreeModel *model;
        gchar *text;
-       gint row;
-       if (user_data->dlg.selected_clist==NULL)
-               return;
+       GtkTreeSelection *selection;
+       GtkTreePath *path;
 
-       clist = user_data->dlg.selected_clist;
-       row = user_data->dlg.selected_row + 1;
+       selection = user_data->dlg.selected_list_sel;
 
-       while (gtk_clist_get_text(clist,row,6,&text)) {
-               if (strcmp(text, OK_TEXT) != 0) {
-                       gtk_clist_select_row(clist, row, 0);
-                       gtk_clist_moveto(clist, row, 0, 0.5, 0);
-                       return;
-               }
-               ++row;
-       }
+       if (selection==NULL)
+               return;
 
-       /* wrap around */
-       row = 0;
-       while (gtk_clist_get_text(clist,row,6,&text) && row<user_data->dlg.selected_row) {
-               if (strcmp(text, OK_TEXT) != 0) {
-                       gtk_clist_select_row(clist, row, 0);
-                       gtk_clist_moveto(clist, row, 0, 0.5, 0);
-                       return;
+try_again:
+       if (gtk_tree_selection_get_selected (selection, &model, &iter)){
+               while (gtk_tree_model_iter_next (model,&iter)) {
+                       gtk_tree_model_get (model, &iter, STATUS_COLUMN, &text, -1);
+                       if (strcmp(text, OK_TEXT) != 0) {
+                               gtk_tree_selection_select_iter (selection, &iter);
+                               path = gtk_tree_model_get_path(model, &iter);
+                               gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW( user_data->dlg.selected_list),
+                                               path,
+                                               NULL, FALSE, 0, 0);
+                               gtk_tree_path_free(path);
+                               g_free (text);
+                               return;
+                       }
+                       g_free (text);
+               }
+               /* wrap around */
+               if (user_data->dlg.number_of_nok>1){
+                       /* Get the first iter and select it before starting over */
+                       gtk_tree_model_get_iter_first(model, &iter);
+                       gtk_tree_selection_select_iter (selection, &iter);
+                       goto try_again;
                }
-               ++row;
        }
 }
 
+
 /****************************************************************************/
 /* when we want to save the information */
-static void save_csv_as_ok_cb(GtkWidget *bt _U_, gpointer fs /*user_data_t *user_data*/ _U_)
+static gboolean save_csv_as_ok_cb(GtkWidget *w _U_, gpointer fc /*user_data_t *user_data*/)
 {
        gchar *g_dest;
        GtkWidget *rev, *forw, *both;
        user_data_t *user_data;
-       
+
+       GtkListStore *store;
+       GtkTreeIter iter;
+       GtkTreeModel *model;
+       gboolean more_items = TRUE;
+
+       /* To Hold data from the list row */
+       guint                   packet;         /* Packet                               */
+       guint                   sequence;       /* Sequence                             */
+       gfloat                  delta;          /* Delta(ms)                    */
+       gfloat                  jitter;         /* Jitter(ms)                   */
+       gfloat                  ipbw;           /* IP BW(kbps)                  */
+       gboolean                marker;         /* Marker                               */
+       char *                  status_str;     /* Status                               */
+       char *                  date_str;       /* Date                                 */
+       guint                   length;         /* Length                               */
+
+
        FILE *fp;
-       char *columnText;
-       int i,j;
-       
-       g_dest = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
-       
+       int j;
+
+       g_dest = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
+
        /* Perhaps the user specified a directory instead of a file.
-       Check whether they did. */
+        * Check whether they did.
+        */
        if (test_for_directory(g_dest) == EISDIR) {
                /* It's a directory - set the file selection box to display it. */
                set_last_open_dir(g_dest);
                g_free(g_dest);
-               file_selection_set_current_folder(fs, get_last_open_dir());
-               return;
+               file_selection_set_current_folder(fc, get_last_open_dir());
+               gtk_file_chooser_set_current_name(fc, "");
+               return FALSE; /* run the dialog again */
        }
-       
-       rev = (GtkWidget*)OBJECT_GET_DATA(bt, "reversed_rb");
-       forw = (GtkWidget*)OBJECT_GET_DATA(bt, "forward_rb");
-       both = (GtkWidget*)OBJECT_GET_DATA(bt, "both_rb");
-       user_data = (user_data_t*)OBJECT_GET_DATA(bt, "user_data");
-       
+
+       rev  = (GtkWidget*)g_object_get_data(G_OBJECT(fc), "reversed_rb");
+       forw = (GtkWidget*)g_object_get_data(G_OBJECT(fc), "forward_rb");
+       both = (GtkWidget*)g_object_get_data(G_OBJECT(fc), "both_rb");
+       user_data = (user_data_t*)g_object_get_data(G_OBJECT(fc), "user_data");
+
        if (GTK_TOGGLE_BUTTON(forw)->active || GTK_TOGGLE_BUTTON(both)->active) {
-               fp = fopen(g_dest, "w");
+               fp = ws_fopen(g_dest, "w");
                if (fp == NULL) {
                        open_failure_alert_box(g_dest, errno, TRUE);
-                       return;
+                       g_free(g_dest);
+                       return TRUE; /* we're done */
                }
-               
+
                if (GTK_TOGGLE_BUTTON(both)->active) {
                        fprintf(fp, "Forward\n");
                        if (ferror(fp)) {
                                write_failure_alert_box(g_dest, errno);
                                fclose(fp);
-                               return;
+                               g_free(g_dest);
+                               return TRUE; /* we're done */
                        }
                }
-               
+
                for(j = 0; j < NUM_COLS; j++) {
                        if (j == 0) {
                                fprintf(fp,"%s",titles[j]);
@@ -2226,50 +1941,77 @@ static void save_csv_as_ok_cb(GtkWidget *bt _U_, gpointer fs /*user_data_t *user
                if (ferror(fp)) {
                        write_failure_alert_box(g_dest, errno);
                        fclose(fp);
-                       return;
+                       g_free(g_dest);
+                       return TRUE;
                }
-               for (i = 0; i < GTK_CLIST(user_data->dlg.clist_fwd)->rows; i++) {
-                       for(j = 0; j < GTK_CLIST(user_data->dlg.clist_fwd)->columns; j++) {
-                               gtk_clist_get_text(GTK_CLIST(user_data->dlg.clist_fwd),i,j,&columnText);
-                               if (j == 0) {
-                                       fprintf(fp,"%s",columnText);
-                               } else {
-                                       fprintf(fp,",%s",columnText);
-                               }
-                       }
-                       fprintf(fp,"\n");
-                       if (ferror(fp)) {
-                               write_failure_alert_box(g_dest, errno);
-                               fclose(fp);
-                               return;
-                       }
-               }
-               
+               model = gtk_tree_view_get_model(GTK_TREE_VIEW(user_data->dlg.list_fwd));
+               store = GTK_LIST_STORE(model);
+               if( gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter) ) {
+                                               
+                        while (more_items){
+                                gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 
+                                        0, &packet,
+                                        1, &sequence,
+                                        2, &delta,
+                                        3, &jitter,
+                                        4, &ipbw,
+                                        5, &marker,
+                                        6, &status_str,
+                                        7, &date_str,
+                                        8, &length,
+                                        -1);
+                                fprintf(fp, "%u",packet);
+                                fprintf(fp, ",%u", sequence);
+                                fprintf(fp, ",%.2f", delta);
+                                fprintf(fp, ",%.2f", jitter);
+                                fprintf(fp, ",%.2f", ipbw);
+                                fprintf(fp, ",%s", marker? "SET" : "");
+                                fprintf(fp, ",%s", status_str);
+                                fprintf(fp, ",%s", date_str);
+                                fprintf(fp, ",%u", length);
+                                fprintf(fp,"\n");
+                                g_free(status_str);
+                                g_free(date_str);
+                                if (ferror(fp)) {
+                                        write_failure_alert_box(g_dest, errno);
+                                        fclose(fp);
+                                        g_free(g_dest);
+                                        return TRUE; /* we're done */
+                                }
+
+                                more_items = gtk_tree_model_iter_next (model,&iter);
+                        }
+                }
+
                if (fclose(fp) == EOF) {
                        write_failure_alert_box(g_dest, errno);
-                       return;
+                       g_free(g_dest);
+                       return TRUE; /* we're done */
                }
        }
-       
+
        if (GTK_TOGGLE_BUTTON(rev)->active || GTK_TOGGLE_BUTTON(both)->active) {
-               
+
                if (GTK_TOGGLE_BUTTON(both)->active) {
-                       fp = fopen(g_dest, "a");
+                       fp = ws_fopen(g_dest, "a");
                        if (fp == NULL) {
                                open_failure_alert_box(g_dest, errno, TRUE);
-                               return;
+                               g_free(g_dest);
+                               return TRUE; /* we're done */
                        }
                        fprintf(fp, "\nReverse\n");
                        if (ferror(fp)) {
                                write_failure_alert_box(g_dest, errno);
                                fclose(fp);
-                               return;
+                               g_free(g_dest);
+                               return TRUE; /* we're done */
                        }
                } else {
-                       fp = fopen(g_dest, "w");
+                       fp = ws_fopen(g_dest, "w");
                        if (fp == NULL) {
                                open_failure_alert_box(g_dest, errno, TRUE);
-                               return;
+                               g_free(g_dest);
+                               return TRUE; /* we're done */
                        }
                }
                for(j = 0; j < NUM_COLS; j++) {
@@ -2283,40 +2025,67 @@ static void save_csv_as_ok_cb(GtkWidget *bt _U_, gpointer fs /*user_data_t *user
                if (ferror(fp)) {
                        write_failure_alert_box(g_dest, errno);
                        fclose(fp);
-                       return;
-               }
-               for (i = 0; i < GTK_CLIST(user_data->dlg.clist_rev)->rows; i++) {
-                       for(j = 0; j < GTK_CLIST(user_data->dlg.clist_rev)->columns; j++) {
-                               gtk_clist_get_text(GTK_CLIST(user_data->dlg.clist_rev),i,j,&columnText);
-                               if (j == 0) {
-                                       fprintf(fp,"%s",columnText);
-                               } else {
-                                       fprintf(fp,",%s",columnText);
-                               }
-                       }
-                       fprintf(fp,"\n");
-                       if (ferror(fp)) {
-                               write_failure_alert_box(g_dest, errno);
-                               fclose(fp);
-                               return;
-                       }
+                       g_free(g_dest);
+                       return TRUE; /* we're done */
                }
+               model = gtk_tree_view_get_model(GTK_TREE_VIEW(user_data->dlg.list_rev));
+               store = GTK_LIST_STORE(model);
+               if( gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter) ) {
+
+                       more_items = TRUE;
+                        
+                        while (more_items){
+                                gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 
+                                        0, &packet,
+                                        1, &sequence,
+                                        2, &delta,
+                                        3, &jitter,
+                                        4, &ipbw,
+                                        5, &marker,
+                                        6, &status_str,
+                                        7, &date_str,
+                                        8, &length,
+                                        -1);
+                                fprintf(fp, "%u",packet);
+                                fprintf(fp, ",%u", sequence);
+                                fprintf(fp, ",%.2f", delta);
+                                fprintf(fp, ",%.2f", jitter);
+                                fprintf(fp, ",%.2f", ipbw);
+                                fprintf(fp, ",%s", marker? "SET" : "");
+                                fprintf(fp, ",%s", status_str);
+                                fprintf(fp, ",%s", date_str);
+                                fprintf(fp, ",%u", length);
+                                fprintf(fp,"\n");
+                                g_free(status_str);
+                                g_free(date_str);
+                                if (ferror(fp)) {
+                                        write_failure_alert_box(g_dest, errno);
+                                        fclose(fp);
+                                        g_free(g_dest);
+                                        return TRUE; /* we're done */
+                                }
+
+                                more_items = gtk_tree_model_iter_next (model,&iter);
+                        }
+                }
                if (fclose(fp) == EOF) {
                        write_failure_alert_box(g_dest, errno);
-                       return;
+                       g_free(g_dest);
+                       return TRUE; /* we're done */
                }
        }
 
-       window_destroy(GTK_WIDGET(user_data->dlg.save_csv_as_w));
+       g_free(g_dest);
+       return TRUE; /* we're done */
 }
 
-static void save_csv_as_destroy_cb(GtkWidget *win _U_, user_data_t *user_data _U_)
+static void save_csv_as_destroy_cb(GtkWidget *win _U_, user_data_t *user_data)
 {
        user_data->dlg.save_csv_as_w = NULL;
 }
 
 /* when the user wants to save the csv information in a file */
-static void save_csv_as_cb(GtkWidget *bt _U_, user_data_t *user_data _U_)
+static void save_csv_as_cb(GtkWidget *bt _U_, user_data_t *user_data)
 {
        GtkWidget *vertb;
        GtkWidget *table1;
@@ -2326,88 +2095,113 @@ static void save_csv_as_cb(GtkWidget *bt _U_, user_data_t *user_data _U_)
        GtkWidget *forward_rb;
        GtkWidget *reversed_rb;
        GtkWidget *both_rb;
-       GtkWidget *ok_bt;
-       
+
+#if 0  /* XXX: GtkFileChooserDialog/gtk_dialog_run currently being used is effectively modal so this is not req'd */
        if (user_data->dlg.save_csv_as_w != NULL) {
                /* There's already a Save CSV info dialog box; reactivate it. */
                reactivate_window(user_data->dlg.save_csv_as_w);
                return;
        }
-       
-       user_data->dlg.save_csv_as_w = gtk_file_selection_new("Ethereal: Save Data As CSV");
-       
+#endif
+       user_data->dlg.save_csv_as_w = gtk_file_chooser_dialog_new("Wireshark: Save Data As CSV",
+                                                                  GTK_WINDOW(user_data->dlg.notebook), 
+                                                                  GTK_FILE_CHOOSER_ACTION_SAVE,
+                                                                  GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                                                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                                                  NULL);
+#if GTK_CHECK_VERSION(2,8,0)
+       gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(user_data->dlg.save_csv_as_w), TRUE);
+#endif
+       gtk_window_set_transient_for(GTK_WINDOW(user_data->dlg.save_csv_as_w),GTK_WINDOW(user_data->dlg.window));
+
        /* Container for each row of widgets */
        vertb = gtk_vbox_new(FALSE, 0);
-       gtk_container_border_width(GTK_CONTAINER(vertb), 5);
-       gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(user_data->dlg.save_csv_as_w)->action_area),
-               vertb, FALSE, FALSE, 0);
+       gtk_container_set_border_width(GTK_CONTAINER(vertb), 5);
+       gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(user_data->dlg.save_csv_as_w), vertb);
        gtk_widget_show (vertb);
-       
+
        table1 = gtk_table_new (2, 4, FALSE);
        gtk_widget_show (table1);
        gtk_box_pack_start (GTK_BOX (vertb), table1, FALSE, FALSE, 0);
        gtk_container_set_border_width (GTK_CONTAINER (table1), 10);
        gtk_table_set_row_spacings (GTK_TABLE (table1), 20);
-       
+
        label_format = gtk_label_new ("Format: Comma Separated Values");
        gtk_widget_show (label_format);
        gtk_table_attach (GTK_TABLE (table1), label_format, 0, 3, 0, 1,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
-       
-       channels_label = gtk_label_new ("Channels:");
+
+       gtk_misc_set_alignment (GTK_MISC (label_format), 0, 0.5f);
+
+
+       channels_label = gtk_label_new ("Channels:    ");
        gtk_widget_show (channels_label);
        gtk_table_attach (GTK_TABLE (table1), channels_label, 0, 1, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       gtk_misc_set_alignment (GTK_MISC (channels_label), 0, 0.5);
-       
+       gtk_misc_set_alignment (GTK_MISC (channels_label), 0, 0.5f);
+
        forward_rb = gtk_radio_button_new_with_label (channels_group, "forward  ");
-       channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (forward_rb));
+       channels_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (forward_rb));
        gtk_widget_show (forward_rb);
        gtk_table_attach (GTK_TABLE (table1), forward_rb, 1, 2, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
-       reversed_rb = gtk_radio_button_new_with_label (channels_group, "reversed");
-       channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (reversed_rb));
+
+       reversed_rb = gtk_radio_button_new_with_label (channels_group, "reversed    ");
+       channels_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (reversed_rb));
        gtk_widget_show (reversed_rb);
        gtk_table_attach (GTK_TABLE (table1), reversed_rb, 2, 3, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
+
        both_rb = gtk_radio_button_new_with_label (channels_group, "both");
-       channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (both_rb));
+       channels_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (both_rb));
        gtk_widget_show (both_rb);
        gtk_table_attach (GTK_TABLE (table1), both_rb, 3, 4, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
+
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(both_rb), TRUE);
-       
-       ok_bt = GTK_FILE_SELECTION(user_data->dlg.save_csv_as_w)->ok_button;
-       OBJECT_SET_DATA(ok_bt, "forward_rb", forward_rb);
-       OBJECT_SET_DATA(ok_bt, "reversed_rb", reversed_rb);
-       OBJECT_SET_DATA(ok_bt, "both_rb", both_rb);
-       OBJECT_SET_DATA(ok_bt, "user_data", user_data);
-       SIGNAL_CONNECT(ok_bt, "clicked", save_csv_as_ok_cb,
-               user_data->dlg.save_csv_as_w);
-       
-       window_set_cancel_button(user_data->dlg.save_csv_as_w, 
-               GTK_FILE_SELECTION(user_data->dlg.save_csv_as_w)->cancel_button, NULL);
-       
-       SIGNAL_CONNECT(user_data->dlg.save_csv_as_w, "delete_event", window_delete_event_cb, NULL);
-       SIGNAL_CONNECT(user_data->dlg.save_csv_as_w, "destroy",
-               save_csv_as_destroy_cb, user_data);
-       
+
+       g_object_set_data(G_OBJECT(user_data->dlg.save_csv_as_w), "forward_rb", forward_rb);
+       g_object_set_data(G_OBJECT(user_data->dlg.save_csv_as_w), "reversed_rb", reversed_rb);
+       g_object_set_data(G_OBJECT(user_data->dlg.save_csv_as_w), "both_rb", both_rb);
+       g_object_set_data(G_OBJECT(user_data->dlg.save_csv_as_w), "user_data", user_data);
+
+       g_signal_connect(user_data->dlg.save_csv_as_w, "delete_event", 
+               G_CALLBACK(window_delete_event_cb), NULL);
+       g_signal_connect(user_data->dlg.save_csv_as_w, "destroy",
+               G_CALLBACK(save_csv_as_destroy_cb), user_data);
+
        gtk_widget_show(user_data->dlg.save_csv_as_w);
        window_present(user_data->dlg.save_csv_as_w);
+
+       /* "Run" the GtkFileChooserDialog.                                              */
+       /* Upon exit: If "Accept" run the OK callback.                                  */
+       /*            If the OK callback returns with a FALSE status, re-run the dialog.*/
+       /*            Destroy the window.                                               */
+       /* XXX: If the OK callback pops up an alert box (eg: for an error) it *must*    */
+       /*      return with a TRUE status so that the dialog window will be destroyed.  */
+       /*      Trying to re-run the dialog after popping up an alert box will not work */
+       /*       since the user will not be able to dismiss the alert box.              */
+       /*      The (somewhat unfriendly) effect: the user must re-invoke the           */
+       /*      GtkFileChooserDialog whenever the OK callback pops up an alert box.     */
+       /*                                                                              */
+       /*      ToDo: use GtkFileChooserWidget in a dialog window instead of            */
+       /*            GtkFileChooserDialog.                                             */
+       while (gtk_dialog_run(GTK_DIALOG(user_data->dlg.save_csv_as_w)) == GTK_RESPONSE_ACCEPT) {
+               if (save_csv_as_ok_cb(NULL, user_data->dlg.save_csv_as_w)) {
+                       break; /* we're done */
+               }
+       }
+       window_destroy(user_data->dlg.save_csv_as_w);
 }
 
 
 /****************************************************************************/
-static void save_voice_as_destroy_cb(GtkWidget *win _U_, user_data_t *user_data _U_)
+static void save_voice_as_destroy_cb(GtkWidget *win _U_, user_data_t *user_data)
 {
        /* Note that we no longer have a Save voice info dialog box. */
        user_data->dlg.save_voice_as_w = NULL;
@@ -2418,107 +2212,96 @@ static void save_voice_as_destroy_cb(GtkWidget *win _U_, user_data_t *user_data
 /* XXX what about endians here? could go something wrong? */
 static gboolean copy_file(gchar *dest, gint channels, gint format, user_data_t *user_data)
 {
-       int to_fd, forw_fd, rev_fd, fread = 0, rread = 0, fwritten, rwritten;
-       gchar f_pd[1];
-       gchar r_pd[1];
-       gint16 tmp;
-       gchar pd[1];
+       FILE *to_stream, *forw_stream, *rev_stream;
+       size_t fwritten, rwritten;
+       int f_rawvalue, r_rawvalue, rawvalue;
+       gint16 sample;
+       gchar pd[4];
        guint32 f_write_silence = 0;
        guint32 r_write_silence = 0;
        progdlg_t *progbar;
        guint32 progbar_count, progbar_quantum, progbar_nextstep = 0, count = 0;
        gboolean stop_flag = FALSE;
+       size_t nchars;
 
-       forw_fd = open(user_data->f_tempname, O_RDONLY | O_BINARY);
-       if (forw_fd < 0) 
+       forw_stream = ws_fopen(user_data->f_tempname, "rb");
+       if (forw_stream == NULL)
                return FALSE;
-       rev_fd = open(user_data->r_tempname, O_RDONLY | O_BINARY);
-       if (rev_fd < 0) {
-               close(forw_fd); 
+       rev_stream = ws_fopen(user_data->r_tempname, "rb");
+       if (rev_stream == NULL) {
+               fclose(forw_stream);
                return FALSE;
        }
 
        /* open file for saving */
-       to_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
-       if (to_fd < 0) {
-               close(forw_fd);
-               close(rev_fd);
+       to_stream = ws_fopen(dest, "wb");
+       if (to_stream == NULL) {
+               fclose(forw_stream);
+               fclose(rev_stream);
                return FALSE;
        }
 
-       progbar = create_progress_dlg("Saving voice in a file", dest, &stop_flag);
+       progbar = create_progress_dlg("Saving voice in a file", dest, TRUE, &stop_flag);
 
        if      (format == SAVE_AU_FORMAT) /* au format */
        {
                /* First we write the .au header. XXX Hope this is endian independant */
                /* the magic word 0x2e736e64 == .snd */
-               *pd = (unsigned char)0x2e; write(to_fd, pd, 1);
-               *pd = (unsigned char)0x73; write(to_fd, pd, 1);
-               *pd = (unsigned char)0x6e; write(to_fd, pd, 1);
-               *pd = (unsigned char)0x64; write(to_fd, pd, 1);
+               phtonl(pd, 0x2e736e64);
+               nchars=fwrite(pd, 1, 4, to_stream);
                /* header offset == 24 bytes */
-               *pd = (unsigned char)0x00; write(to_fd, pd, 1);
-               write(to_fd, pd, 1);
-               write(to_fd, pd, 1);
-               *pd = (unsigned char)0x18; write(to_fd, pd, 1);
-               /* total length, it is permited to set this to 0xffffffff */
-               *pd = (unsigned char)0xff; write(to_fd, pd, 1); 
-               write(to_fd, pd, 1); 
-               write(to_fd, pd, 1); 
-               write(to_fd, pd, 1);
-               /* encoding format == 8 bit ulaw */
-               *pd = (unsigned char)0x00; write(to_fd, pd, 1);
-               write(to_fd, pd, 1);
-               write(to_fd, pd, 1);
-               *pd = (unsigned char)0x01; write(to_fd, pd, 1);
+               phtonl(pd, 24);
+               nchars=fwrite(pd, 1, 4, to_stream);
+               /* total length; it is permitted to set this to 0xffffffff */
+               phtonl(pd, -1);
+               nchars=fwrite(pd, 1, 4, to_stream);
+               /* encoding format == 16-bit linear PCM */
+               phtonl(pd, 3);
+               nchars=fwrite(pd, 1, 4, to_stream);
                /* sample rate == 8000 Hz */
-               *pd = (unsigned char)0x00; write(to_fd, pd, 1);
-               write(to_fd, pd, 1);
-               *pd = (unsigned char)0x1f; write(to_fd, pd, 1);
-               *pd = (unsigned char)0x40; write(to_fd, pd, 1);
+               phtonl(pd, 8000);
+               nchars=fwrite(pd, 1, 4, to_stream);
                /* channels == 1 */
-               *pd = (unsigned char)0x00; write(to_fd, pd, 1);
-               write(to_fd, pd, 1);
-               write(to_fd, pd, 1);
-               *pd = (unsigned char)0x01; write(to_fd, pd, 1);
-       
-       
+               phtonl(pd, 1);
+               nchars=fwrite(pd, 1, 4, to_stream);
+
+
                switch (channels) {
                        /* only forward direction */
-                       case 1: {
+                       case SAVE_FORWARD_DIRECTION_MASK: {
                                progbar_count = user_data->forward.saveinfo.count;
                                progbar_quantum = user_data->forward.saveinfo.count/100;
-                               while ((fread = read(forw_fd, f_pd, 1)) > 0) {
-                                       if(stop_flag) 
+                               while ((f_rawvalue = getc(forw_stream)) != EOF) {
+                                       if(stop_flag)
                                                break;
                                        if((count > progbar_nextstep) && (count <= progbar_count)) {
-                                               update_progress_dlg(progbar, 
+                                               update_progress_dlg(progbar,
                                                        (gfloat) count/progbar_count, "Saving");
                                                progbar_nextstep = progbar_nextstep + progbar_quantum;
                                        }
                                        count++;
 
                                        if (user_data->forward.statinfo.pt == PT_PCMU){
-                                               tmp = (gint16 )ulaw2linear(*f_pd);
-                                               *pd = (unsigned char)linear2ulaw(tmp);
+                                               sample = ulaw2linear((unsigned char)f_rawvalue);
+                                               phtons(pd, sample);
                                        }
                                        else if(user_data->forward.statinfo.pt == PT_PCMA){
-                                               tmp = (gint16 )alaw2linear(*f_pd);
-                                               *pd = (unsigned char)linear2ulaw(tmp);
+                                               sample = alaw2linear((unsigned char)f_rawvalue);
+                                               phtons(pd, sample);
                                        }
                                        else{
-                                               close(forw_fd);
-                                               close(rev_fd);
-                                               close(to_fd);
+                                               fclose(forw_stream);
+                                               fclose(rev_stream);
+                                               fclose(to_stream);
                                                destroy_progress_dlg(progbar);
                                                return FALSE;
                                        }
-                                       
-                                       fwritten = write(to_fd, pd, 1);
-                                       if ((fwritten < fread) || (fwritten < 0) || (fread < 0)) {
-                                               close(forw_fd);
-                                               close(rev_fd);
-                                               close(to_fd);
+
+                                       fwritten = fwrite(pd, 1, 2, to_stream);
+                                       if (fwritten < 2) {
+                                               fclose(forw_stream);
+                                               fclose(rev_stream);
+                                               fclose(to_stream);
                                                destroy_progress_dlg(progbar);
                                                return FALSE;
                                        }
@@ -2526,40 +2309,40 @@ static gboolean copy_file(gchar *dest, gint channels, gint format, user_data_t *
                                break;
                        }
                        /* only reversed direction */
-                       case 2: {
+                       case SAVE_REVERSE_DIRECTION_MASK: {
                                progbar_count = user_data->reversed.saveinfo.count;
                                progbar_quantum = user_data->reversed.saveinfo.count/100;
-                               while ((rread = read(rev_fd, r_pd, 1)) > 0) {
-                                       if(stop_flag) 
+                               while ((r_rawvalue = getc(rev_stream)) != EOF) {
+                                       if(stop_flag)
                                                break;
                                        if((count > progbar_nextstep) && (count <= progbar_count)) {
-                                               update_progress_dlg(progbar, 
+                                               update_progress_dlg(progbar,
                                                        (gfloat) count/progbar_count, "Saving");
                                                progbar_nextstep = progbar_nextstep + progbar_quantum;
                                        }
                                        count++;
 
-                                       if (user_data->forward.statinfo.pt == PT_PCMU){
-                                               tmp = (gint16 )ulaw2linear(*r_pd);
-                                               *pd = (unsigned char)linear2ulaw(tmp);
+                                       if (user_data->reversed.statinfo.pt == PT_PCMU){
+                                               sample = ulaw2linear((unsigned char)r_rawvalue);
+                                               phtons(pd, sample);
                                        }
-                                       else if(user_data->forward.statinfo.pt == PT_PCMA){
-                                               tmp = (gint16 )alaw2linear(*r_pd);
-                                               *pd = (unsigned char)linear2ulaw(tmp);
+                                       else if(user_data->reversed.statinfo.pt == PT_PCMA){
+                                               sample = alaw2linear((unsigned char)r_rawvalue);
+                                               phtons(pd, sample);
                                        }
                                        else{
-                                               close(forw_fd);
-                                               close(rev_fd);
-                                               close(to_fd);
+                                               fclose(forw_stream);
+                                               fclose(rev_stream);
+                                               fclose(to_stream);
                                                destroy_progress_dlg(progbar);
                                                return FALSE;
                                        }
-                                       
-                                       rwritten = write(to_fd, pd, 1);
-                                       if ((rwritten < rread) || (rwritten < 0) || (rread < 0)) {
-                                               close(forw_fd);
-                                               close(rev_fd);
-                                               close(to_fd);
+
+                                       rwritten = fwrite(pd, 1, 2, to_stream);
+                                       if (rwritten < 2) {
+                                               fclose(forw_stream);
+                                               fclose(rev_stream);
+                                               fclose(to_stream);
                                                destroy_progress_dlg(progbar);
                                                return FALSE;
                                        }
@@ -2567,12 +2350,12 @@ static gboolean copy_file(gchar *dest, gint channels, gint format, user_data_t *
                                break;
                        }
                        /* both directions */
-                       default: {
-                               (user_data->forward.saveinfo.count > user_data->reversed.saveinfo.count) ? 
-                                               (progbar_count = user_data->forward.saveinfo.count) : 
+                       case SAVE_BOTH_DIRECTION_MASK: {
+                               (user_data->forward.saveinfo.count > user_data->reversed.saveinfo.count) ?
+                                               (progbar_count = user_data->forward.saveinfo.count) :
                                                        (progbar_count = user_data->reversed.saveinfo.count);
                                progbar_quantum = progbar_count/100;
-                               /* since conversation in one way can start later than in the other one, 
+                               /* since conversation in one way can start later than in the other one,
                                 * we have to write some silence information for one channel */
                                if (user_data->forward.statinfo.start_time > user_data->reversed.statinfo.start_time) {
                                        f_write_silence = (guint32)
@@ -2583,57 +2366,73 @@ static gboolean copy_file(gchar *dest, gint channels, gint format, user_data_t *
                                                ((user_data->reversed.statinfo.start_time-user_data->forward.statinfo.start_time)*8000);
                                }
                                for(;;) {
-                                       if(stop_flag) 
+                                       if(stop_flag)
                                                break;
                                        if((count > progbar_nextstep) && (count <= progbar_count)) {
-                                               update_progress_dlg(progbar, 
+                                               update_progress_dlg(progbar,
                                                        (gfloat) count/progbar_count, "Saving");
                                                progbar_nextstep = progbar_nextstep + progbar_quantum;
                                        }
                                        count++;
                                        if(f_write_silence > 0) {
-                                               rread = read(rev_fd, r_pd, 1);
-                                               *f_pd = 0;
-                                               fread = 1;
+                                               r_rawvalue = getc(rev_stream);
+                                               switch (user_data->forward.statinfo.reg_pt) {
+                                               case PT_PCMU:
+                                                       f_rawvalue = SILENCE_PCMU;
+                                                       break;
+                                               case PT_PCMA:
+                                                       f_rawvalue = SILENCE_PCMA;
+                                                       break;
+                                               default:
+                                                       f_rawvalue = 0;
+                                                       break;
+                                               }
                                                f_write_silence--;
                                        }
                                        else if(r_write_silence > 0) {
-                                               fread = read(forw_fd, f_pd, 1);
-                                               *r_pd = 0;
-                                               rread = 1;
+                                               f_rawvalue = getc(forw_stream);
+                                               switch (user_data->reversed.statinfo.reg_pt) {
+                                               case PT_PCMU:
+                                                       r_rawvalue = SILENCE_PCMU;
+                                                       break;
+                                               case PT_PCMA:
+                                                       r_rawvalue = SILENCE_PCMA;
+                                                       break;
+                                               default:
+                                                       r_rawvalue = 0;
+                                                       break;
+                                               }
                                                r_write_silence--;
                                        }
                                        else {
-                                               fread = read(forw_fd, f_pd, 1); 
-                                               rread = read(rev_fd, r_pd, 1);
+                                               f_rawvalue = getc(forw_stream);
+                                               r_rawvalue = getc(rev_stream);
                                        }
-                                       if ((rread == 0) && (fread == 0)) 
+                                       if ((r_rawvalue == EOF) && (f_rawvalue == EOF))
                                                break;
                                        if ((user_data->forward.statinfo.pt == PT_PCMU) && (user_data->reversed.statinfo.pt == PT_PCMU)){
-                                               tmp = ulaw2linear(*r_pd);
-                                               tmp += ulaw2linear(*f_pd);
-                                               *pd = (unsigned char)linear2ulaw(tmp/2);
+                                               sample = (ulaw2linear((unsigned char)r_rawvalue) + ulaw2linear((unsigned char)f_rawvalue)) / 2;
+                                               phtons(pd, sample);
                                        }
                                        else if((user_data->forward.statinfo.pt == PT_PCMA) && (user_data->reversed.statinfo.pt == PT_PCMA)){
-                                               tmp = alaw2linear(*r_pd);
-                                               tmp += alaw2linear(*f_pd);
-                                               *pd = (unsigned char)linear2ulaw(tmp/2);
+                                               sample = (alaw2linear((unsigned char)r_rawvalue) + alaw2linear((unsigned char)f_rawvalue)) / 2;
+                                               phtons(pd, sample);
                                        }
                                        else
                                        {
-                                               close(forw_fd);
-                                               close(rev_fd);
-                                               close(to_fd);
+                                               fclose(forw_stream);
+                                               fclose(rev_stream);
+                                               fclose(to_stream);
                                                destroy_progress_dlg(progbar);
                                                return FALSE;
                                        }
-                                       
-                                       
-                                       rwritten = write(to_fd, pd, 1);
-                                       if ((rwritten < 0) || (rread < 0) || (fread < 0)) {
-                                               close(forw_fd);
-                                               close(rev_fd);
-                                               close(to_fd);
+
+
+                                       rwritten = fwrite(pd, 1, 2, to_stream);
+                                       if (rwritten < 2) {
+                                               fclose(forw_stream);
+                                               fclose(rev_stream);
+                                               fclose(to_stream);
                                                destroy_progress_dlg(progbar);
                                                return FALSE;
                                        }
@@ -2643,50 +2442,48 @@ static gboolean copy_file(gchar *dest, gint channels, gint format, user_data_t *
        }
        else if (format == SAVE_RAW_FORMAT)     /* raw format */
        {
-               int fd;
+               FILE *stream;
                switch (channels) {
                        /* only forward direction */
-                       case 1: {
+                       case SAVE_FORWARD_DIRECTION_MASK: {
                                progbar_count = user_data->forward.saveinfo.count;
                                progbar_quantum = user_data->forward.saveinfo.count/100;
-                               fd = forw_fd;
+                               stream = forw_stream;
                                break;
                        }
                        /* only reversed direction */
-                       case 2: {
+                       case SAVE_REVERSE_DIRECTION_MASK: {
                                progbar_count = user_data->reversed.saveinfo.count;
                                progbar_quantum = user_data->reversed.saveinfo.count/100;
-                               fd = rev_fd;
+                               stream = rev_stream;
                                break;
                        }
                        default: {
-                               close(forw_fd);
-                               close(rev_fd);
-                               close(to_fd);
+                               fclose(forw_stream);
+                               fclose(rev_stream);
+                               fclose(to_stream);
                                destroy_progress_dlg(progbar);
                                return FALSE;
                        }
                }
 
-               
+
 
                /* XXX how do you just copy the file? */
-               while ((rread = read(fd, pd, 1)) > 0) {
-                       if(stop_flag) 
+               while ((rawvalue = getc(stream)) != EOF) {
+                       if(stop_flag)
                                break;
                        if((count > progbar_nextstep) && (count <= progbar_count)) {
-                               update_progress_dlg(progbar, 
+                               update_progress_dlg(progbar,
                                        (gfloat) count/progbar_count, "Saving");
                                progbar_nextstep = progbar_nextstep + progbar_quantum;
                        }
                        count++;
 
-                       rwritten = write(to_fd, pd, 1);
-
-                       if ((rwritten < rread) || (rwritten < 0) || (rread < 0)) {
-                               close(forw_fd);
-                               close(rev_fd);
-                               close(to_fd);
+                       if (putc(rawvalue, to_stream) == EOF) {
+                               fclose(forw_stream);
+                               fclose(rev_stream);
+                               fclose(to_stream);
                                destroy_progress_dlg(progbar);
                                return FALSE;
                        }
@@ -2694,9 +2491,9 @@ static gboolean copy_file(gchar *dest, gint channels, gint format, user_data_t *
        }
 
        destroy_progress_dlg(progbar);
-       close(forw_fd);
-       close(rev_fd);
-       close(to_fd);
+       fclose(forw_stream);
+       fclose(rev_stream);
+       fclose(to_stream);
        return TRUE;
 }
 
@@ -2704,71 +2501,76 @@ static gboolean copy_file(gchar *dest, gint channels, gint format, user_data_t *
 /****************************************************************************/
 /* the user wants to save in a file */
 /* XXX support for different formats is currently commented out */
-static void save_voice_as_ok_cb(GtkWidget *ok_bt _U_, gpointer fs _U_)
+static gboolean save_voice_as_ok_cb(GtkWidget *w _U_, gpointer fc)
 {
        gchar *g_dest;
-       /*GtkWidget *wav, *au, *sw;*/
+       /*GtkWidget *wav, *sw;*/
        GtkWidget *au, *raw;
        GtkWidget *rev, *forw, *both;
        user_data_t *user_data;
-       gint channels , format;
-       
-       g_dest = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
-       
+       gint channels, format;
+
+       g_dest = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
+
        /* Perhaps the user specified a directory instead of a file.
-       Check whether they did. */
+        * Check whether they did.
+        */
        if (test_for_directory(g_dest) == EISDIR) {
                /* It's a directory - set the file selection box to display it. */
                set_last_open_dir(g_dest);
                g_free(g_dest);
-               file_selection_set_current_folder(fs, get_last_open_dir());
-               return;
+               file_selection_set_current_folder(fc, get_last_open_dir());
+               gtk_file_chooser_set_current_name(fc, "");
+               return FALSE; /* run the dialog again */
        }
-       
-       /*wav = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "wav_rb");
-       sw = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "sw_rb");*/
-       au = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "au_rb");
-       raw = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "raw_rb");
-       rev = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "reversed_rb");
-       forw = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "forward_rb");
-       both = (GtkWidget *)OBJECT_GET_DATA(ok_bt, "both_rb");
-       user_data = (user_data_t *)OBJECT_GET_DATA(ok_bt, "user_data");
-       
+
+#if 0
+       wav  = (GtkWidget *)g_object_get_data(G_OBJECT(fc), "wav_rb");
+       sw   = (GtkWidget *)g_object_get_data(G_OBJECT(fc), "sw_rb");
+#endif
+       au   = (GtkWidget *)g_object_get_data(G_OBJECT(fc), "au_rb");
+       raw  = (GtkWidget *)g_object_get_data(G_OBJECT(fc), "raw_rb");
+       rev  = (GtkWidget *)g_object_get_data(G_OBJECT(fc), "reversed_rb");
+       forw = (GtkWidget *)g_object_get_data(G_OBJECT(fc), "forward_rb");
+       both = (GtkWidget *)g_object_get_data(G_OBJECT(fc), "both_rb");
+       user_data = (user_data_t *)g_object_get_data(G_OBJECT(fc), "user_data");
+
        /* XXX user clicks the ok button, but we know we can't save the voice info because f.e.
        * we don't support that codec. So we pop up a warning. Maybe it would be better to
        * disable the ok button or disable the buttons for direction if only one is not ok. The
-       * problem is if we open the save voice dialog and then click the refresh button and maybe 
+       * problem is if we open the save voice dialog and then click the refresh button and maybe
        * the state changes, so we can't save anymore. In this case we should be able to update
        * the buttons. For now it is easier if we put the warning when the ok button is pressed.
        */
-       
+
        /* we can not save in both directions */
        if ((user_data->forward.saveinfo.saved == FALSE) && (user_data->reversed.saveinfo.saved == FALSE) && (GTK_TOGGLE_BUTTON (both)->active)) {
                /* there are many combinations here, we just exit when first matches */
-               if ((user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_CODEC) || 
+               if ((user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_CODEC) ||
                        (user_data->reversed.saveinfo.error_type == TAP_RTP_WRONG_CODEC))
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: Unsupported codec!");
-               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_LENGTH) || 
+               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_LENGTH) ||
                        (user_data->reversed.saveinfo.error_type == TAP_RTP_WRONG_LENGTH))
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: Wrong length of captured packets!");
-               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_PADDING_ERROR) || 
+               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_PADDING_ERROR) ||
                        (user_data->reversed.saveinfo.error_type == TAP_RTP_PADDING_ERROR))
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: RTP data with padding!");
-               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_SHORT_FRAME) || 
+               else if ((user_data->forward.saveinfo.error_type == TAP_RTP_SHORT_FRAME) ||
                        (user_data->reversed.saveinfo.error_type == TAP_RTP_SHORT_FRAME))
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: Not all data in all packets was captured!");
                else
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: File I/O problem!");
-               return;
+               g_free(g_dest);
+               return TRUE; /* we're done */
        }
        /* we can not save forward direction */
        else if ((user_data->forward.saveinfo.saved == FALSE) && ((GTK_TOGGLE_BUTTON (forw)->active) ||
-               (GTK_TOGGLE_BUTTON (both)->active))) {  
+               (GTK_TOGGLE_BUTTON (both)->active))) {
                if (user_data->forward.saveinfo.error_type == TAP_RTP_WRONG_CODEC)
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save forward direction in a file: Unsupported codec!");
@@ -2784,11 +2586,12 @@ static void save_voice_as_ok_cb(GtkWidget *ok_bt _U_, gpointer fs _U_)
                else
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save forward direction in a file: File I/O problem!");
-               return;
+               g_free(g_dest);
+               return TRUE; /* we're done */
        }
        /* we can not save reversed direction */
        else if ((user_data->reversed.saveinfo.saved == FALSE) && ((GTK_TOGGLE_BUTTON (rev)->active) ||
-               (GTK_TOGGLE_BUTTON (both)->active))) {  
+               (GTK_TOGGLE_BUTTON (both)->active))) {
                if (user_data->reversed.saveinfo.error_type == TAP_RTP_WRONG_CODEC)
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save reversed direction in a file: Unsupported codec!");
@@ -2798,7 +2601,7 @@ static void save_voice_as_ok_cb(GtkWidget *ok_bt _U_, gpointer fs _U_)
                else if (user_data->reversed.saveinfo.error_type == TAP_RTP_PADDING_ERROR)
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save reversed direction in a file: RTP data with padding!");
-               else if (user_data->forward.saveinfo.error_type == TAP_RTP_SHORT_FRAME)
+               else if (user_data->reversed.saveinfo.error_type == TAP_RTP_SHORT_FRAME)
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save reversed direction in a file: Not all data in all packets was captured!");
                else if (user_data->reversed.saveinfo.error_type == TAP_RTP_NO_DATA)
@@ -2807,24 +2610,31 @@ static void save_voice_as_ok_cb(GtkWidget *ok_bt _U_, gpointer fs _U_)
                else
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save reversed direction in a file: File I/O problem!");
-               return;
+               g_free(g_dest);
+               return TRUE; /* we're done */
        }
-       
-       /*if (GTK_TOGGLE_BUTTON (wav)->active)
-       format = 1;
-       else */if (GTK_TOGGLE_BUTTON (au)->active)
-       format = SAVE_AU_FORMAT;/*
+
+#if 0
+       if (GTK_TOGGLE_BUTTON (wav)->active)
+               format = SAVE_WAV_FORMAT;
+       else 
+#endif
+       if (GTK_TOGGLE_BUTTON (au)->active)
+               format = SAVE_AU_FORMAT;
+#if 0
        else if (GTK_TOGGLE_BUTTON (sw)->active)
-       format = 3;*/
+               format = SAVE_SW_FORMAT;
+#endif
        else if (GTK_TOGGLE_BUTTON (raw)->active)
-               format =SAVE_RAW_FORMAT;
-       
-       
+               format = SAVE_RAW_FORMAT;
+       else
+               format = SAVE_NONE_FORMAT;
+
        if (GTK_TOGGLE_BUTTON (rev)->active)
                channels = SAVE_REVERSE_DIRECTION_MASK;
        else if (GTK_TOGGLE_BUTTON (both)->active)
                channels = SAVE_BOTH_DIRECTION_MASK;
-       else 
+       else
                channels = SAVE_FORWARD_DIRECTION_MASK;
 
        /* direction/format validity*/
@@ -2834,91 +2644,107 @@ static void save_voice_as_ok_cb(GtkWidget *ok_bt _U_, gpointer fs _U_)
                if ((channels & SAVE_FORWARD_DIRECTION_MASK) && (user_data->forward.statinfo.pt != PT_PCMA) && (user_data->forward.statinfo.pt != PT_PCMU)){
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                                "Can't save in a file: saving in au format supported only for alaw/ulaw streams");
-                       return;
+                       g_free(g_dest);
+                       return TRUE; /* we're done */
                }
                if ((channels & SAVE_REVERSE_DIRECTION_MASK) && (user_data->reversed.statinfo.pt != PT_PCMA) && (user_data->reversed.statinfo.pt != PT_PCMU)){
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                                "Can't save in a file: saving in au format supported only for alaw/ulaw streams");
-                       return;
+                       g_free(g_dest);
+                       return TRUE; /* we're done */
                }
                /* make sure pt's don't differ */
-               if ((channels == SAVE_REVERSE_DIRECTION_MASK) && (user_data->forward.statinfo.pt != user_data->forward.statinfo.pt)){
+               if ((channels == SAVE_BOTH_DIRECTION_MASK) && (user_data->forward.statinfo.pt != user_data->reversed.statinfo.pt)){
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                                "Can't save in a file: Forward and reverse direction differ in type");
-                       return;
+                       g_free(g_dest);
+                       return TRUE; /* we're done */
                }
        }
        else if (format == SAVE_RAW_FORMAT)
        {
                /* can't save raw in both directions */
-               if (channels == SAVE_REVERSE_DIRECTION_MASK){
+               if (channels == SAVE_BOTH_DIRECTION_MASK){
                        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                                "Can't save in a file: Unable to save raw data in both directions");
-                       return;
+                       g_free(g_dest);
+                       return TRUE; /* we're done */
                }
        }
        else
        {
                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Can't save in a file: Invalid save format");
-               return;
+               g_free(g_dest);
+               return TRUE; /* we're done */
        }
-       
+
        if(!copy_file(g_dest, channels, format, user_data)) {
                /* XXX - report the error type! */
                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                       "An error occured while saving voice in a file!");
-               return;
+                       "An error occurred while saving voice in a file!");
+               g_free(g_dest);
+               return TRUE; /* we're done */
        }
-       
-       window_destroy(GTK_WIDGET(user_data->dlg.save_voice_as_w));
+
+       g_free(g_dest);
+       return TRUE; /* we're done */
 }
 
 /****************************************************************************/
 /* when the user wants to save the voice information in a file */
 /* XXX support for different formats is currently commented out */
-static void on_save_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
+static void on_save_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data)
 {
        GtkWidget *vertb;
        GtkWidget *table1;
        GtkWidget *label_format;
        GtkWidget *channels_label;
-       GSList *format_group = NULL;
-       GSList *channels_group = NULL;
+       GSList    *format_group = NULL;
+       GSList    *channels_group = NULL;
        GtkWidget *forward_rb;
        GtkWidget *reversed_rb;
        GtkWidget *both_rb;
        /*GtkWidget *wav_rb;  GtkWidget *sw_rb;*/
        GtkWidget *au_rb;
        GtkWidget *raw_rb;
-       GtkWidget *ok_bt;
-       
+
        /* if we can't save in a file: wrong codec, cut packets or other errors */
-       /* shold the error arise here or later when you click ok button ? 
-       * if we do it here, then we must disable the refresh button, so we don't do it here */
-       
+       /* Should the error arise here or later when you click ok button ?
+        * if we do it here, then we must disable the refresh button, so we don't do it here
+        */
+
+#if 0  /* XXX: GtkFileChooserDialog/gtk_dialog_run currently being used is effectively modal so this is not req'd */
        if (user_data->dlg.save_voice_as_w != NULL) {
                /* There's already a Save voice info dialog box; reactivate it. */
                reactivate_window(user_data->dlg.save_voice_as_w);
                return;
        }
-       
+#endif
     /* XXX - use file_selection from dlg_utils instead! */
-       user_data->dlg.save_voice_as_w = gtk_file_selection_new("Ethereal: Save Payload As ...");
-       
+       user_data->dlg.save_voice_as_w = gtk_file_chooser_dialog_new("Wireshark: Save Payload As ...",
+                                                                       GTK_WINDOW(user_data->dlg.notebook),
+                                                                       GTK_FILE_CHOOSER_ACTION_SAVE,
+                                    GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                    NULL);
+#if GTK_CHECK_VERSION(2,8,0)
+       gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(user_data->dlg.save_voice_as_w), TRUE);
+#endif
+       gtk_window_set_transient_for(GTK_WINDOW(user_data->dlg.save_voice_as_w),GTK_WINDOW(user_data->dlg.window));
+
        /* Container for each row of widgets */
        vertb = gtk_vbox_new(FALSE, 0);
-       gtk_container_border_width(GTK_CONTAINER(vertb), 5);
-       gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(user_data->dlg.save_voice_as_w)->action_area),
-               vertb, FALSE, FALSE, 0);
+       gtk_container_set_border_width(GTK_CONTAINER(vertb), 5);
+       gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(user_data->dlg.save_voice_as_w), vertb);
        gtk_widget_show (vertb);
-       
+
        table1 = gtk_table_new (2, 4, FALSE);
        gtk_widget_show (table1);
        gtk_box_pack_start (GTK_BOX (vertb), table1, FALSE, FALSE, 0);
        gtk_container_set_border_width (GTK_CONTAINER (table1), 10);
        gtk_table_set_row_spacings (GTK_TABLE (table1), 20);
-       
+
        /*label_format = gtk_label_new ("Format: .au (ulaw, 8 bit, 8000 Hz, mono) ");
        gtk_widget_show (label_format);
        gtk_table_attach (GTK_TABLE (table1), label_format, 0, 3, 0, 1,
@@ -2931,79 +2757,83 @@ static void on_save_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
 
-       gtk_misc_set_alignment (GTK_MISC (label_format), 0, 0.5);
+       gtk_misc_set_alignment (GTK_MISC (label_format), 0, 0.5f);
 
        raw_rb = gtk_radio_button_new_with_label (format_group, ".raw");
-       format_group = gtk_radio_button_group (GTK_RADIO_BUTTON (raw_rb));
+       format_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (raw_rb));
        gtk_widget_show (raw_rb);
        gtk_table_attach (GTK_TABLE (table1), raw_rb, 1, 2, 0, 1,
        (GtkAttachOptions) (GTK_FILL),
        (GtkAttachOptions) (0), 0, 0);
-       
-         
+
+
        au_rb = gtk_radio_button_new_with_label (format_group, ".au");
-       format_group = gtk_radio_button_group (GTK_RADIO_BUTTON (au_rb));
+       format_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (au_rb));
        gtk_widget_show (au_rb);
        gtk_table_attach (GTK_TABLE (table1), au_rb, 3, 4, 0, 1,
        (GtkAttachOptions) (GTK_FILL),
        (GtkAttachOptions) (0), 0, 0);
-       
-       /* we support .au - ulaw*/ 
-       /*      wav_rb = gtk_radio_button_new_with_label (format_group, ".wav");
-       format_group = gtk_radio_button_group (GTK_RADIO_BUTTON (wav_rb));
+
+#if 0
+       /* we support .au - ulaw*/
+       wav_rb = gtk_radio_button_new_with_label (format_group, ".wav");
+       format_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (wav_rb));
        gtk_widget_show (wav_rb);
        gtk_table_attach (GTK_TABLE (table1), wav_rb, 1, 2, 0, 1,
        (GtkAttachOptions) (GTK_FILL),
        (GtkAttachOptions) (0), 0, 0);
-       
+
          sw_rb = gtk_radio_button_new_with_label (format_group, "8 kHz, 16 bit  ");
-         format_group = gtk_radio_button_group (GTK_RADIO_BUTTON (sw_rb));
+         format_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (sw_rb));
          gtk_widget_show (sw_rb);
          gtk_table_attach (GTK_TABLE (table1), sw_rb, 2, 3, 0, 1,
          (GtkAttachOptions) (GTK_FILL),
          (GtkAttachOptions) (0), 0, 0);
          au_rb = gtk_radio_button_new_with_label (format_group, ".au");
-         format_group = gtk_radio_button_group (GTK_RADIO_BUTTON (au_rb));
+         format_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (au_rb));
          gtk_widget_show (au_rb);
          gtk_table_attach (GTK_TABLE (table1), au_rb, 3, 4, 0, 1,
          (GtkAttachOptions) (GTK_FILL),
          (GtkAttachOptions) (0), 0, 0);
-       */ 
-       
-       channels_label = gtk_label_new ("Channels:");
+#endif
+
+       channels_label = gtk_label_new ("Channels:    ");
        gtk_widget_show (channels_label);
        gtk_table_attach (GTK_TABLE (table1), channels_label, 0, 1, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       gtk_misc_set_alignment (GTK_MISC (channels_label), 0, 0.5);
-       
-       forward_rb = gtk_radio_button_new_with_label (channels_group, "forward  ");
-       channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (forward_rb));
+       gtk_misc_set_alignment (GTK_MISC (channels_label), 0, 0.5f);
+
+       forward_rb = gtk_radio_button_new_with_label (channels_group, "forward    ");
+       channels_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (forward_rb));
        gtk_widget_show (forward_rb);
        gtk_table_attach (GTK_TABLE (table1), forward_rb, 1, 2, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
-       reversed_rb = gtk_radio_button_new_with_label (channels_group, "reversed");
-       channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (reversed_rb));
+
+       reversed_rb = gtk_radio_button_new_with_label (channels_group, "reversed    ");
+       channels_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (reversed_rb));
        gtk_widget_show (reversed_rb);
        gtk_table_attach (GTK_TABLE (table1), reversed_rb, 2, 3, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
+
        both_rb = gtk_radio_button_new_with_label (channels_group, "both");
-       channels_group = gtk_radio_button_group (GTK_RADIO_BUTTON (both_rb));
+       channels_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (both_rb));
        gtk_widget_show (both_rb);
        gtk_table_attach (GTK_TABLE (table1), both_rb, 3, 4, 1, 2,
                (GtkAttachOptions) (GTK_FILL),
                (GtkAttachOptions) (0), 0, 0);
-       
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(both_rb), TRUE);
-       
-       /* if one direction is nok we don't allow saving 
+
+
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(forward_rb), TRUE);
+
+#if 0
+       /* if one direction is nok we don't allow saving
        XXX this is not ok since the user can click the refresh button and cause changes
        but we can not update this window. So we move all the decision on the time the ok
        button is clicked
+       */
        if (user_data->forward.saved == FALSE) {
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(reversed_rb), TRUE);
        gtk_widget_set_sensitive(forward_rb, FALSE);
@@ -3013,30 +2843,45 @@ static void on_save_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
        gtk_widget_set_sensitive(reversed_rb, FALSE);
        gtk_widget_set_sensitive(both_rb, FALSE);
        }
-       */
-       
-       ok_bt = GTK_FILE_SELECTION(user_data->dlg.save_voice_as_w)->ok_button;
-       /*OBJECT_SET_DATA(ok_bt, "wav_rb", wav_rb);*/
-       OBJECT_SET_DATA(ok_bt, "au_rb", au_rb);
-       /*OBJECT_SET_DATA(ok_bt, "sw_rb", sw_rb);*/
-       OBJECT_SET_DATA(ok_bt, "raw_rb", raw_rb);
-       OBJECT_SET_DATA(ok_bt, "forward_rb", forward_rb);
-       OBJECT_SET_DATA(ok_bt, "reversed_rb", reversed_rb);
-       OBJECT_SET_DATA(ok_bt, "both_rb", both_rb);
-       OBJECT_SET_DATA(ok_bt, "user_data", user_data);
-       SIGNAL_CONNECT(ok_bt, "clicked", save_voice_as_ok_cb,
-                       user_data->dlg.save_voice_as_w);
-
-    window_set_cancel_button(user_data->dlg.save_voice_as_w, 
-      GTK_FILE_SELECTION(user_data->dlg.save_voice_as_w)->cancel_button, window_cancel_button_cb);
-
-    SIGNAL_CONNECT(user_data->dlg.save_voice_as_w, "delete_event", 
-                        window_delete_event_cb, NULL);
-       SIGNAL_CONNECT(user_data->dlg.save_voice_as_w, "destroy",
-                        save_voice_as_destroy_cb, user_data);
+ #endif
+
+       /*g_object_set_data(G_OBJECT(user_data->dlg.save_voice_as_w), "wav_rb", wav_rb);*/
+       g_object_set_data(G_OBJECT(user_data->dlg.save_voice_as_w), "au_rb", au_rb);
+       /*g_object_set_data(G_OBJECT(user_data->dlg.save_voice_as_w), "sw_rb", sw_rb);*/
+       g_object_set_data(G_OBJECT(user_data->dlg.save_voice_as_w), "raw_rb", raw_rb);
+       g_object_set_data(G_OBJECT(user_data->dlg.save_voice_as_w), "forward_rb", forward_rb);
+       g_object_set_data(G_OBJECT(user_data->dlg.save_voice_as_w), "reversed_rb", reversed_rb);
+       g_object_set_data(G_OBJECT(user_data->dlg.save_voice_as_w), "both_rb", both_rb);
+       g_object_set_data(G_OBJECT(user_data->dlg.save_voice_as_w), "user_data", user_data);
+
+       g_signal_connect(user_data->dlg.save_voice_as_w, "delete_event",
+                        G_CALLBACK(window_delete_event_cb), NULL);
+       g_signal_connect(user_data->dlg.save_voice_as_w, "destroy",
+                        G_CALLBACK(save_voice_as_destroy_cb), user_data);
 
        gtk_widget_show(user_data->dlg.save_voice_as_w);
-    window_present(user_data->dlg.save_voice_as_w);
+       window_present(user_data->dlg.save_voice_as_w);
+
+       /* "Run" the GtkFileChooserDialog.                                              */
+       /* Upon exit: If "Accept" run the OK callback.                                  */
+       /*            If the OK callback returns with a FALSE status, re-run the dialog.*/
+       /*            Destroy the window.                                               */
+       /* XXX: If the OK callback pops up an alert box (eg: for an error) it *must*    */
+       /*      return with a TRUE status so that the dialog window will be destroyed.  */
+       /*      Trying to re-run the dialog after popping up an alert box will not work */
+       /*       since the user will not be able to dismiss the alert box.              */
+       /*      The (somewhat unfriendly) effect: the user must re-invoke the           */
+       /*      GtkFileChooserDialog whenever the OK callback pops up an alert box.     */
+       /*                                                                              */
+       /*      ToDo: use GtkFileChooserWidget in a dialog window instead of            */
+       /*            GtkFileChooserDialog.                                             */
+       while (gtk_dialog_run(GTK_DIALOG(user_data->dlg.save_voice_as_w)) == GTK_RESPONSE_ACCEPT) {
+               if (save_voice_as_ok_cb(NULL, user_data->dlg.save_voice_as_w)) {
+                       break;  /* we're done */
+               }
+       }
+       window_destroy(user_data->dlg.save_voice_as_w);
+
 }
 
 
@@ -3044,42 +2889,86 @@ static void on_save_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_)
 /* when we are finished with redisection, we add the label for the statistic */
 static void draw_stat(user_data_t *user_data)
 {
-       gchar label_max[200];
+       gchar label_max[300];
        guint32 f_expected = (user_data->forward.statinfo.stop_seq_nr + user_data->forward.statinfo.cycles*65536)
                - user_data->forward.statinfo.start_seq_nr + 1;
        guint32 r_expected = (user_data->reversed.statinfo.stop_seq_nr + user_data->reversed.statinfo.cycles*65536)
                - user_data->reversed.statinfo.start_seq_nr + 1;
-       gint32 f_lost = f_expected - user_data->forward.statinfo.total_nr;
-       gint32 r_lost = r_expected - user_data->reversed.statinfo.total_nr;
+       guint32 f_total_nr = user_data->forward.statinfo.total_nr;
+       guint32 r_total_nr = user_data->reversed.statinfo.total_nr;
+       gint32 f_lost = f_expected - f_total_nr;
+       gint32 r_lost = r_expected - r_total_nr;
+       double f_sumt = user_data->forward.statinfo.sumt;
+       double f_sumTS = user_data->forward.statinfo.sumTS;
+       double f_sumt2 = user_data->forward.statinfo.sumt2;
+       double f_sumtTS = user_data->forward.statinfo.sumtTS;
+
+       double r_sumt = user_data->reversed.statinfo.sumt;
+       double r_sumTS = user_data->reversed.statinfo.sumTS;
+       double r_sumt2 = user_data->reversed.statinfo.sumt2;
+       double r_sumtTS = user_data->reversed.statinfo.sumtTS;
        double f_perc, r_perc;
+       double f_clock_drift = 1.0;
+       double r_clock_drift = 1.0;
+       double f_duration = user_data->forward.statinfo.time - user_data->forward.statinfo.start_time;
+       double r_duration = user_data->reversed.statinfo.time - user_data->reversed.statinfo.start_time;
+       guint32 f_clock_rate = user_data->forward.statinfo.clock_rate;
+       guint32 r_clock_rate = user_data->reversed.statinfo.clock_rate;
+
+       if (f_clock_rate == 0){
+               f_clock_rate = 1;
+       }
+
+       if (r_clock_rate == 0){
+               r_clock_rate = 1;
+       }
+
        if (f_expected){
                f_perc = (double)(f_lost*100)/(double)f_expected;
        } else {
                f_perc = 0;
        }
-        if (r_expected){
-                r_perc = (double)(r_lost*100)/(double)r_expected;
-        } else {
-                r_perc = 0;
-        } 
-               
-       g_snprintf(label_max, 199, "Max delta = %f sec at packet no. %u \n"
+    if (r_expected){
+            r_perc = (double)(r_lost*100)/(double)r_expected;
+    } else {
+            r_perc = 0;
+    }
+
+       if ((f_total_nr >0)&&(f_sumt2 > 0)){
+               f_clock_drift = (f_total_nr * f_sumtTS - f_sumt * f_sumTS) / (f_total_nr * f_sumt2 - f_sumt * f_sumt);
+       }
+       if ((r_total_nr >0)&&(r_sumt2 > 0)){
+               r_clock_drift = (r_total_nr * r_sumtTS - r_sumt * r_sumTS) / (r_total_nr * r_sumt2 - r_sumt * r_sumt);
+       }
+       g_snprintf(label_max, sizeof(label_max), "Max delta = %.2f ms at packet no. %u \n"
+               "Max jitter = %.2f ms. Mean jitter = %.2f ms.\n"
+               "Max skew = %.2f ms.\n"
                "Total RTP packets = %u   (expected %u)   Lost RTP packets = %d (%.2f%%)"
-               "   Sequence errors = %u",
+               "   Sequence errors = %u \n"
+               "Duration %.2f s (%.0f ms clock drift, corresponding to %.0f Hz (%+.2f%%)",
                user_data->forward.statinfo.max_delta, user_data->forward.statinfo.max_nr,
-               user_data->forward.statinfo.total_nr,
-               f_expected, f_lost, f_perc, user_data->forward.statinfo.sequence);
+               user_data->forward.statinfo.max_jitter,user_data->forward.statinfo.mean_jitter,
+               user_data->forward.statinfo.max_skew,
+               f_expected, f_expected, f_lost, f_perc, 
+               user_data->forward.statinfo.sequence,
+               f_duration/1000,f_duration*(f_clock_drift-1.0),f_clock_drift*f_clock_rate,100.0*(f_clock_drift-1.0));
 
        gtk_label_set_text(GTK_LABEL(user_data->dlg.label_stats_fwd), label_max);
+       gtk_label_set_selectable (GTK_LABEL(user_data->dlg.label_stats_fwd),TRUE);
 
-       g_snprintf(label_max, 199, "Max delta = %f sec at packet no. %u \n"
+       g_snprintf(label_max, sizeof(label_max), "Max delta = %.2f ms at packet no. %u \n"
+               "Max jitter = %.2f ms. Mean jitter = %.2f ms.\n"
                "Total RTP packets = %u   (expected %u)   Lost RTP packets = %d (%.2f%%)"
-               "   Sequence errors = %u",
+               "   Sequence errors = %u \n"
+               "Duration %.0f s (%.0f ms clock drift, corresponding to %.0f Hz (%+.2f%%)",
                user_data->reversed.statinfo.max_delta, user_data->reversed.statinfo.max_nr,
-               user_data->reversed.statinfo.total_nr,
-               r_expected, r_lost, r_perc, user_data->reversed.statinfo.sequence);
+               user_data->reversed.statinfo.max_jitter,user_data->reversed.statinfo.mean_jitter,
+               r_expected, r_expected, r_lost, r_perc, 
+               user_data->reversed.statinfo.sequence,
+               r_duration/1000,r_duration*(r_clock_drift-1.0),r_clock_drift*r_clock_rate,100.0*(r_clock_drift-1.0));
 
        gtk_label_set_text(GTK_LABEL(user_data->dlg.label_stats_rev), label_max);
+       gtk_label_set_selectable (GTK_LABEL(user_data->dlg.label_stats_rev),TRUE);
 
        return ;
 }
@@ -3087,212 +2976,269 @@ static void draw_stat(user_data_t *user_data)
 
 
 /****************************************************************************/
-/* append a line to clist */
-static void add_to_clist(GtkCList *clist, guint32 number, guint16 seq_num,
-                         double delta, double jitter, double bandwidth, gchar *status, gboolean marker,
-                         gchar *timeStr, guint32 pkt_len, GdkColor *color)
+/* append a line to list */
+static void add_to_list(GtkWidget *list, user_data_t * user_data, guint32 number, guint16 seq_num,
+                         double delta, double jitter,double skew, double bandwidth, gchar *status, gboolean marker,
+                         gchar *timeStr, guint32 pkt_len, gchar *color_str, guint32 flags)
 {
-       guint added_row;
-       gchar *data[9];
-       gchar field[9][32];
-       char *savelocale;
-
-       data[0]=&field[0][0];
-       data[1]=&field[1][0];
-       data[2]=&field[2][0];
-       data[3]=&field[3][0];
-       data[4]=&field[4][0];
-       data[5]=&field[5][0];
-       data[6]=&field[6][0];
-       data[7]=&field[7][0];
-       data[8]=&field[8][0];
-
-       /* save the current locale */
-       savelocale = setlocale(LC_NUMERIC, NULL);
-       /* switch to "C" locale to avoid problems with localized decimal separators
-               in g_snprintf("%f") functions */
-       setlocale(LC_NUMERIC, "C");
-       g_snprintf(field[0], 20, "%u", number);
-       g_snprintf(field[1], 20, "%u", seq_num);
-       g_snprintf(field[2], 20, "%.2f", delta);
-       g_snprintf(field[3], 20, "%.2f", jitter);
-       g_snprintf(field[4], 20, "%.2f", bandwidth);
-       g_snprintf(field[5], 20, "%s", marker? "SET" : "");
-       g_snprintf(field[6], 40, "%s", status);
-       g_snprintf(field[7], 32, "%s", timeStr);
-       g_snprintf(field[8], 20, "%u", pkt_len);
-       /* restore previous locale setting */
-       setlocale(LC_NUMERIC, savelocale);
-
-       added_row = gtk_clist_append(GTK_CLIST(clist), data);
-       gtk_clist_set_row_data(GTK_CLIST(clist), added_row, GUINT_TO_POINTER(number));
-       gtk_clist_set_background(GTK_CLIST(clist), added_row, color);
-}
-
+    GtkListStore *list_store;
 
-/****************************************************************************/
-/* callback for sorting columns of clist */
-static gint rtp_sort_column(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2)
-{
-       char *text1 = NULL;
-       char *text2 = NULL;
-       int i1, i2;
-       double f1, f2;
-
-       const GtkCListRow *row1 = ptr1;
-       const GtkCListRow *row2 = ptr2;
-
-       text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text;
-       text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text;
-
-       switch(clist->sort_column){
-       /* columns representing strings */
-       case 5:
-       case 6:
-       case 7:
-               return strcmp (text1, text2);
-       /* columns representing ints */
-       case 0:
-       case 1:
-       case 8:
-               i1=atoi(text1);
-               i2=atoi(text2);
-               return i1-i2;
-       /* columns representing floats */
-       case 2:
-       case 3:
-       case 4:
-               f1=atof(text1);
-               f2=atof(text2);
-               if (fabs(f1-f2)<0.0000005)
-                       return 0;
-               if (f1<f2)
-                       return -1;
-               return 1;
+       if (strcmp(status, OK_TEXT) != 0) {
+               user_data->dlg.number_of_nok++;
        }
-       g_assert_not_reached();
-       return 0;
-}
 
+    list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (list))); /* Get store */
 
-/****************************************************************************/
-static void
-click_column_cb(GtkCList *clist, gint column, gpointer data)
-{
-       column_arrows *col_arrows = (column_arrows *) data;
-       int i;
-
-       gtk_clist_freeze(clist);
-
-       for (i = 0; i < NUM_COLS; i++) {
-               gtk_widget_hide(col_arrows[i].ascend_pm);
-               gtk_widget_hide(col_arrows[i].descend_pm);
-       }
-
-       if (column == clist->sort_column) {
-               if (clist->sort_type == GTK_SORT_ASCENDING) {
-                       clist->sort_type = GTK_SORT_DESCENDING;
-                       gtk_widget_show(col_arrows[column].descend_pm);
-               } else {
-                       clist->sort_type = GTK_SORT_ASCENDING;
-                       gtk_widget_show(col_arrows[column].ascend_pm);
-               }
-       } else {
-               clist->sort_type = GTK_SORT_ASCENDING;
-               gtk_widget_show(col_arrows[column].ascend_pm);
-               gtk_clist_set_sort_column(clist, column);
+       /* Creates a new row at position. iter will be changed to point to this new row. 
+        * If position is larger than the number of rows on the list, then the new row will be appended to the list.
+        * The row will be filled with the values given to this function.
+        * :
+        * should generally be preferred when inserting rows in a sorted list store.
+        */
+#if GTK_CHECK_VERSION(2,6,0)
+       gtk_list_store_insert_with_values( list_store , &user_data->dlg.iter, G_MAXINT,
+#else
+       gtk_list_store_append  (list_store, &user_data->dlg.iter);
+       gtk_list_store_set  (list_store, &user_data->dlg.iter,
+#endif
+                PACKET_COLUMN, number,
+                SEQUENCE_COLUMN, seq_num,
+                               DELTA_COLUMN, delta,
+                               JITTER_COLUMN, jitter,
+                               SKEW_COLUMN, skew,
+                               IPBW_COLUMN, bandwidth,
+                               MARKER_COLUMN, marker,
+                               STATUS_COLUMN, (char *)status,
+                               DATE_COLUMN,  (char *)timeStr,
+                               LENGTH_COLUMN,  pkt_len,
+                               FOREGROUND_COLOR_COL, NULL,
+                               BACKGROUND_COLOR_COL, (char *)color_str,
+                               -1);
+
+       if(flags & STAT_FLAG_FIRST){
+               /* Set first row as active */
+               gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(list)), &user_data->dlg.iter);
        }
-       gtk_clist_thaw(clist);
-
-       gtk_clist_sort(clist);
 }
 
+/****************************************************************************
+* Functions needed to present values from the list
+*/
 
-/****************************************************************************/
-/* Add the packet list */
-static
-GtkWidget* create_clist(user_data_t* user_data)
-{
-       GtkWidget* clist_fwd;
-
-       /* clist for the information */
-       clist_fwd = gtk_clist_new(NUM_COLS);
-       gtk_widget_show(clist_fwd);
-       SIGNAL_CONNECT(clist_fwd, "select_row", on_clist_select_row, user_data);
-
-       gtk_clist_column_titles_show(GTK_CLIST(clist_fwd));
-       gtk_clist_set_compare_func(GTK_CLIST(clist_fwd), rtp_sort_column);
-       gtk_clist_set_sort_column(GTK_CLIST(clist_fwd), 0);
-       gtk_clist_set_sort_type(GTK_CLIST(clist_fwd), GTK_SORT_ASCENDING);
-
-       /* hide date and length column */
-       gtk_clist_set_column_visibility(GTK_CLIST(clist_fwd), 7, FALSE);
-       gtk_clist_set_column_visibility(GTK_CLIST(clist_fwd), 8, FALSE);
-
-       /* column widths and justification */
-       gtk_clist_set_column_width(GTK_CLIST(clist_fwd), 0, 60);
-       gtk_clist_set_column_width(GTK_CLIST(clist_fwd), 1, 75);
-       gtk_clist_set_column_width(GTK_CLIST(clist_fwd), 2, 75);
-       gtk_clist_set_column_width(GTK_CLIST(clist_fwd), 3, 75);
-       gtk_clist_set_column_width(GTK_CLIST(clist_fwd), 4, 50);
-       gtk_clist_set_column_width(GTK_CLIST(clist_fwd), 5, 75);
-       gtk_clist_set_column_justification(GTK_CLIST(clist_fwd), 0, GTK_JUSTIFY_RIGHT);
-       gtk_clist_set_column_justification(GTK_CLIST(clist_fwd), 1, GTK_JUSTIFY_RIGHT);
-       gtk_clist_set_column_justification(GTK_CLIST(clist_fwd), 2, GTK_JUSTIFY_CENTER);
-       gtk_clist_set_column_justification(GTK_CLIST(clist_fwd), 3, GTK_JUSTIFY_CENTER);
-       gtk_clist_set_column_justification(GTK_CLIST(clist_fwd), 4, GTK_JUSTIFY_CENTER);
-       gtk_clist_set_column_justification(GTK_CLIST(clist_fwd), 5, GTK_JUSTIFY_CENTER);
-       gtk_clist_set_column_justification(GTK_CLIST(clist_fwd), 6, GTK_JUSTIFY_CENTER);
-       return clist_fwd;
-}
 
-
-/****************************************************************************/
-/* Add the sort by column feature for a packet clist */
+/* Present boolean value */
+void
+rtp_boolean_data_func (GtkTreeViewColumn *column _U_,
+                           GtkCellRenderer   *renderer,
+                           GtkTreeModel      *model,
+                           GtkTreeIter       *iter,
+                           gpointer           user_data)
+   {
+     gboolean  bool_val;
+     gchar   buf[20];
+        /* the col to get data from is in userdata */
+        gint bool_col = GPOINTER_TO_INT(user_data);
+
+     gtk_tree_model_get(model, iter, bool_col, &bool_val, -1);
+
+        switch(bool_col){
+                case MARKER_COLUMN:
+                        g_strlcpy(buf, bool_val ? "SET" : "", sizeof(buf));
+                        break;
+                default:
+                        g_assert_not_reached();
+                        break;
+        }
+     g_object_set(renderer, "text", buf, NULL);
+   }
+
+/* Create list */
 static
-column_arrows* add_sort_by_column(GtkWidget* window, GtkWidget* clist,
-                                                                 user_data_t* user_data _U_)
+GtkWidget* create_list(user_data_t* user_data)
 {
-       column_arrows *col_arrows;
-       GdkBitmap *ascend_bm, *descend_bm;
-       GdkPixmap *ascend_pm, *descend_pm;
-       GtkStyle *win_style;
-       GtkWidget *column_lb;
-       int i;
 
-       col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) * NUM_COLS);
-       win_style = gtk_widget_get_style(window);
-       ascend_pm = gdk_pixmap_create_from_xpm_d(window->window,
-                       &ascend_bm,
-                       &win_style->bg[GTK_STATE_NORMAL],
-                       (gchar **)clist_ascend_xpm);
-       descend_pm = gdk_pixmap_create_from_xpm_d(window->window,
-                       &descend_bm,
-                       &win_style->bg[GTK_STATE_NORMAL],
-                       (gchar **)clist_descend_xpm);
-
-       for (i=0; i<NUM_COLS; i++) {
-               col_arrows[i].table = gtk_table_new(2, 2, FALSE);
-               gtk_table_set_col_spacings(GTK_TABLE(col_arrows[i].table), 5);
-               column_lb = gtk_label_new(titles[i]);
-               gtk_table_attach(GTK_TABLE(col_arrows[i].table), column_lb, 0, 1, 0, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
-               gtk_widget_show(column_lb);
-
-               col_arrows[i].ascend_pm = gtk_pixmap_new(ascend_pm, ascend_bm);
-               gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].ascend_pm, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
-               col_arrows[i].descend_pm = gtk_pixmap_new(descend_pm, descend_bm);
-               gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].descend_pm, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
-               /* make packet-nr be the default sort order */
-               if (i == 0) {
-                       gtk_widget_show(col_arrows[i].ascend_pm);
-               }
-               gtk_clist_set_column_widget(GTK_CLIST(clist), i, col_arrows[i].table);
-               gtk_widget_show(col_arrows[i].table);
-       }
+    GtkListStore *list_store;
+    GtkWidget *list;
+    GtkTreeViewColumn *column;
+    GtkCellRenderer *renderer;
+    GtkTreeSortable *sortable;
+       GtkTreeView     *list_view;
+       GtkTreeSelection  *selection;
+
+       /* Create the store */
+    list_store = gtk_list_store_new(N_COLUMN,  /* Total number of columns XXX*/
+                               G_TYPE_UINT,            /* Packet                               */
+                               G_TYPE_UINT,            /* Sequence                             */
+                               G_TYPE_FLOAT,   /* Delta(ms)                    */
+                               G_TYPE_FLOAT,   /* Filtered Jitter(ms)  */
+                               G_TYPE_FLOAT,   /* Skew(ms)                             */
+                               G_TYPE_FLOAT,   /* IP BW(kbps)                  */
+                               G_TYPE_BOOLEAN,  /* Marker                              */
+                               G_TYPE_STRING,   /* Status                              */
+                               G_TYPE_STRING,  /* Date                                 */
+                               G_TYPE_UINT,            /* Length                               */
+                                                          G_TYPE_STRING,   /* Foreground color         */
+                                                          G_TYPE_STRING);  /* Background color         */
+
+    /* Create a view */
+    list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
+
+       list_view = GTK_TREE_VIEW(list);
+       sortable = GTK_TREE_SORTABLE(list_store);
+
+#if GTK_CHECK_VERSION(2,6,0)
+       /* Speed up the list display */
+       gtk_tree_view_set_fixed_height_mode(list_view, TRUE);
+#endif
 
-       SIGNAL_CONNECT(clist, "click-column", click_column_cb, col_arrows);
+    /* Setup the sortable columns */
+    gtk_tree_sortable_set_sort_column_id(sortable, PACKET_COLUMN, GTK_SORT_ASCENDING);
+    gtk_tree_view_set_headers_clickable(list_view, FALSE);
 
-       return col_arrows;
+    /* The view now holds a reference.  We can get rid of our own reference */
+    g_object_unref (G_OBJECT (list_store));
+
+    /* 
+        * Create the first column packet, associating the "text" attribute of the
+     * cell_renderer to the first column of the model 
+        */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Packet", renderer, 
+               "text", PACKET_COLUMN, 
+        "foreground", FOREGROUND_COLOR_COL,
+        "background", BACKGROUND_COLOR_COL,
+               NULL);
+    gtk_tree_view_column_set_sort_column_id(column, PACKET_COLUMN);
+    gtk_tree_view_column_set_resizable(column, TRUE);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+    gtk_tree_view_column_set_min_width(column, 55);
+
+       /* Add the column to the view. */
+    gtk_tree_view_append_column (list_view, column);
+
+    /* Sequence. */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Sequence", renderer, 
+               "text", SEQUENCE_COLUMN,
+        "foreground", FOREGROUND_COLOR_COL,
+        "background", BACKGROUND_COLOR_COL,
+               NULL);
+    gtk_tree_view_column_set_sort_column_id(column, SEQUENCE_COLUMN);
+    gtk_tree_view_column_set_resizable(column, TRUE);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+    gtk_tree_view_column_set_min_width(column, 75);
+    gtk_tree_view_append_column (list_view, column);
+
+    /* Delta(ms). */
+    renderer = gtk_cell_renderer_text_new ();
+       column = gtk_tree_view_column_new_with_attributes ("Delta(ms)", renderer, 
+               "text", DELTA_COLUMN, 
+        "foreground", FOREGROUND_COLOR_COL,
+        "background", BACKGROUND_COLOR_COL,
+               NULL);
+       
+       gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func, 
+               GINT_TO_POINTER(DELTA_COLUMN), NULL);
+
+    gtk_tree_view_column_set_sort_column_id(column, DELTA_COLUMN);
+    gtk_tree_view_column_set_resizable(column, TRUE);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+    gtk_tree_view_column_set_min_width(column, 75);
+    gtk_tree_view_append_column (list_view, column);
+
+    /* Jitter(ms). */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Filtered Jitter(ms)", renderer, 
+               "text", JITTER_COLUMN, 
+        "foreground", FOREGROUND_COLOR_COL,
+        "background", BACKGROUND_COLOR_COL,
+               NULL);
+
+       gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func, 
+               GINT_TO_POINTER(JITTER_COLUMN), NULL);
+
+    gtk_tree_view_column_set_sort_column_id(column, JITTER_COLUMN);
+    gtk_tree_view_column_set_resizable(column, TRUE);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+    gtk_tree_view_column_set_min_width(column, 110);
+    gtk_tree_view_append_column (list_view, column);
+
+    /* Skew(ms). */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Skew(ms)", renderer, 
+               "text", SKEW_COLUMN, 
+        "foreground", FOREGROUND_COLOR_COL,
+        "background", BACKGROUND_COLOR_COL,
+               NULL);
+
+       gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func, 
+               GINT_TO_POINTER(SKEW_COLUMN), NULL);
+
+    gtk_tree_view_column_set_sort_column_id(column, SKEW_COLUMN);
+    gtk_tree_view_column_set_resizable(column, TRUE);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+    gtk_tree_view_column_set_min_width(column, 110);
+    gtk_tree_view_append_column (list_view, column);
+
+    /* IP BW(kbps). */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("IP BW(kbps)", renderer, 
+               "text", IPBW_COLUMN, 
+        "foreground", FOREGROUND_COLOR_COL,
+        "background", BACKGROUND_COLOR_COL,
+               NULL);
+
+       gtk_tree_view_column_set_cell_data_func(column, renderer, float_data_func, 
+               GINT_TO_POINTER(IPBW_COLUMN), NULL);
+
+    gtk_tree_view_column_set_sort_column_id(column, IPBW_COLUMN);
+    gtk_tree_view_column_set_resizable(column, TRUE);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+    gtk_tree_view_column_set_min_width(column, 80);
+    gtk_tree_view_append_column (list_view, column);
+
+    /* Marker. */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ("Marker", renderer, 
+               "text", MARKER_COLUMN, 
+        "foreground", FOREGROUND_COLOR_COL,
+        "background", BACKGROUND_COLOR_COL,
+               NULL);
+
+       gtk_tree_view_column_set_cell_data_func(column, renderer, rtp_boolean_data_func, 
+               GINT_TO_POINTER(MARKER_COLUMN), NULL);
+
+    gtk_tree_view_column_set_sort_column_id(column, MARKER_COLUMN);
+    gtk_tree_view_column_set_resizable(column, TRUE);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+    gtk_tree_view_column_set_min_width(column, 60);
+    gtk_tree_view_append_column (list_view, column);
+
+        /* Status. */
+    renderer = gtk_cell_renderer_text_new ();
+    column = gtk_tree_view_column_new_with_attributes ( "Status", renderer, 
+               "text", STATUS_COLUMN,
+        "foreground", FOREGROUND_COLOR_COL,
+        "background", BACKGROUND_COLOR_COL,
+               NULL);
+    gtk_tree_view_column_set_sort_column_id(column, STATUS_COLUMN);
+    gtk_tree_view_column_set_resizable(column, TRUE);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+    gtk_tree_view_column_set_min_width(column, 100);
+    gtk_tree_view_append_column (list_view, column);
+
+    /* Now enable the sorting of each column */
+    gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view), TRUE);
+    gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view), TRUE);
+
+       /* Setup the selection handler */
+       selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
+       gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+       g_signal_connect (G_OBJECT (selection), "changed", /* select_row */
+                  G_CALLBACK (on_list_select_row),
+                  user_data);
+       return list;
 }
 
 /****************************************************************************/
@@ -3300,8 +3246,8 @@ column_arrows* add_sort_by_column(GtkWidget* window, GtkWidget* clist,
 static void create_rtp_dialog(user_data_t* user_data)
 {
        GtkWidget *window = NULL;
-       GtkWidget *clist_fwd;
-       GtkWidget *clist_rev;
+       GtkWidget *list_fwd;
+       GtkWidget *list_rev;
        GtkWidget *label_stats_fwd;
        GtkWidget *label_stats_rev;
        GtkWidget *notebook;
@@ -3315,45 +3261,48 @@ static void create_rtp_dialog(user_data_t* user_data)
 #endif
        GtkWidget *graph_bt;
        gchar label_forward[150];
+       gchar label_forward_tree[150];
        gchar label_reverse[150];
 
        gchar str_ip_src[16];
        gchar str_ip_dst[16];
-       column_arrows *col_arrows_fwd;
-       column_arrows *col_arrows_rev;
-       
-       window = window_new(GTK_WINDOW_TOPLEVEL, "Ethereal: RTP Stream Analysis");
+
+       window = dlg_window_new("Wireshark: RTP Stream Analysis");  /* transient_for top_level */
        gtk_window_set_default_size(GTK_WINDOW(window), 700, 400);
 
        /* Container for each row of widgets */
        main_vb = gtk_vbox_new(FALSE, 2);
-       gtk_container_border_width(GTK_CONTAINER(main_vb), 2);
+       gtk_container_set_border_width(GTK_CONTAINER(main_vb), 2);
        gtk_container_add(GTK_CONTAINER(window), main_vb);
        gtk_widget_show(main_vb);
 
        /* Notebooks... */
-       strcpy(str_ip_src, get_addr_name(&(user_data->ip_src_fwd)));
-       strcpy(str_ip_dst, get_addr_name(&(user_data->ip_dst_fwd)));
+       g_strlcpy(str_ip_src, get_addr_name(&(user_data->ip_src_fwd)), sizeof(str_ip_src));
+       g_strlcpy(str_ip_dst, get_addr_name(&(user_data->ip_dst_fwd)), sizeof(str_ip_dst));
+
+       g_snprintf(label_forward, sizeof(label_forward),
+               "Analysing stream from  %s port %u  to  %s port %u   SSRC = 0x%X",
+               str_ip_src, user_data->port_src_fwd, str_ip_dst, user_data->port_dst_fwd, user_data->ssrc_fwd);
 
-       g_snprintf(label_forward, 149, 
-               "Analysing stream from  %s port %u  to  %s port %u   SSRC = %u", 
+       g_snprintf(label_forward_tree, sizeof(label_forward_tree),
+               "Analysing stream from  %s port %u  to  %s port %u   SSRC = 0x%X",
                str_ip_src, user_data->port_src_fwd, str_ip_dst, user_data->port_dst_fwd, user_data->ssrc_fwd);
 
 
-       strcpy(str_ip_src, get_addr_name(&(user_data->ip_src_rev)));
-       strcpy(str_ip_dst, get_addr_name(&(user_data->ip_dst_rev)));
+       g_strlcpy(str_ip_src, get_addr_name(&(user_data->ip_src_rev)), sizeof(str_ip_src));
+       g_strlcpy(str_ip_dst, get_addr_name(&(user_data->ip_dst_rev)), sizeof(str_ip_dst));
 
-       g_snprintf(label_reverse, 149,
-               "Analysing stream from  %s port %u  to  %s port %u   SSRC = %u", 
+       g_snprintf(label_reverse, sizeof(label_reverse),
+               "Analysing stream from  %s port %u  to  %s port %u   SSRC = 0x%X",
                str_ip_src, user_data->port_src_rev, str_ip_dst, user_data->port_dst_rev, user_data->ssrc_rev);
 
        /* Start a notebook for flipping between sets of changes */
        notebook = gtk_notebook_new();
        gtk_container_add(GTK_CONTAINER(main_vb), notebook);
-       OBJECT_SET_DATA(window, "notebook", notebook);
+       g_object_set_data(G_OBJECT(window), "notebook", notebook);
 
-       user_data->dlg.notebook_signal_id = SIGNAL_CONNECT(notebook, "switch_page", on_notebook_switch_page,
-                       user_data);
+       user_data->dlg.notebook_signal_id =
+        g_signal_connect(notebook, "switch_page", G_CALLBACK(on_notebook_switch_page), user_data);
 
        /* page for forward connection */
        page = gtk_vbox_new(FALSE, 8);
@@ -3370,10 +3319,10 @@ static void create_rtp_dialog(user_data_t* user_data)
        /* scrolled window */
        scrolled_window = scrolled_window_new(NULL, NULL);
 
-       /* packet clist */
-       clist_fwd = create_clist(user_data);
-       gtk_widget_show(clist_fwd);
-       gtk_container_add(GTK_CONTAINER(scrolled_window), clist_fwd);
+       /* packet list */
+       list_fwd = create_list(user_data);
+       gtk_widget_show(list_fwd);
+       gtk_container_add(GTK_CONTAINER(scrolled_window), list_fwd);
        gtk_box_pack_start(GTK_BOX(page), scrolled_window, TRUE, TRUE, 0);
        gtk_widget_show(scrolled_window);
 
@@ -3391,16 +3340,17 @@ static void create_rtp_dialog(user_data_t* user_data)
 
        scrolled_window_r = scrolled_window_new(NULL, NULL);
 
-       clist_rev = create_clist(user_data);
-       gtk_widget_show(clist_rev);
-       gtk_container_add(GTK_CONTAINER(scrolled_window_r), clist_rev);
+       list_rev = create_list(user_data);
+       gtk_widget_show(list_rev);
+       gtk_container_add(GTK_CONTAINER(scrolled_window_r), list_rev);
        gtk_box_pack_start(GTK_BOX(page_r), scrolled_window_r, TRUE, TRUE, 0);
        gtk_widget_show(scrolled_window_r);
 
        label = gtk_label_new("  Reversed Direction  ");
        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_r, label);
 
-       /* page for help&about or future
+       /* page for help&about or future */
+#if 0
        page_help = gtk_hbox_new(FALSE, 5);
        label = gtk_label_new("     Future    ");
        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_help, label);
@@ -3410,7 +3360,7 @@ static void create_rtp_dialog(user_data_t* user_data)
        gtk_container_add(GTK_CONTAINER(frame), text);
        gtk_container_set_border_width(GTK_CONTAINER(frame), 20);
        gtk_box_pack_start(GTK_BOX(page_help), frame, TRUE, TRUE, 0);
-       */
+#endif
 
        /* show all notebooks */
        gtk_widget_show_all(notebook);
@@ -3420,75 +3370,75 @@ static void create_rtp_dialog(user_data_t* user_data)
        gtk_box_pack_start(GTK_BOX(main_vb), box4, FALSE, FALSE, 0);
        gtk_container_set_border_width(GTK_CONTAINER(box4), 10);
        gtk_button_box_set_layout(GTK_BUTTON_BOX (box4), GTK_BUTTONBOX_EDGE);
-       gtk_button_box_set_spacing(GTK_BUTTON_BOX (box4), 0);
-       gtk_button_box_set_child_ipadding(GTK_BUTTON_BOX (box4), 4, 0);
+       gtk_box_set_spacing(GTK_BOX (box4), 0);
        gtk_widget_show(box4);
 
        voice_bt = gtk_button_new_with_label("Save payload...");
        gtk_container_add(GTK_CONTAINER(box4), voice_bt);
        gtk_widget_show(voice_bt);
-       SIGNAL_CONNECT(voice_bt, "clicked", on_save_bt_clicked, user_data);
+       g_signal_connect(voice_bt, "clicked", G_CALLBACK(on_save_bt_clicked), user_data);
 
        csv_bt = gtk_button_new_with_label("Save as CSV...");
        gtk_container_add(GTK_CONTAINER(box4), csv_bt);
        gtk_widget_show(csv_bt);
-       SIGNAL_CONNECT(csv_bt, "clicked", save_csv_as_cb, user_data);
+       g_signal_connect(csv_bt, "clicked", G_CALLBACK(save_csv_as_cb), user_data);
 
-       refresh_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_REFRESH);
+       refresh_bt = gtk_button_new_from_stock(GTK_STOCK_REFRESH);
        gtk_container_add(GTK_CONTAINER(box4), refresh_bt);
        gtk_widget_show(refresh_bt);
-       SIGNAL_CONNECT(refresh_bt, "clicked", on_refresh_bt_clicked, user_data);
+       g_signal_connect(refresh_bt, "clicked", G_CALLBACK(on_refresh_bt_clicked), user_data);
 
-       goto_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_JUMP_TO);
+       goto_bt = gtk_button_new_from_stock(GTK_STOCK_JUMP_TO);
        gtk_container_add(GTK_CONTAINER(box4), goto_bt);
        gtk_widget_show(goto_bt);
-       SIGNAL_CONNECT(goto_bt, "clicked", on_goto_bt_clicked, user_data);
+       g_signal_connect(goto_bt, "clicked", G_CALLBACK(on_goto_bt_clicked_lst), user_data);
 
-        graph_bt = gtk_button_new_with_label("Graph");
+    graph_bt = gtk_button_new_with_label("Graph");
        gtk_container_add(GTK_CONTAINER(box4), graph_bt);
        gtk_widget_show(graph_bt);
-       SIGNAL_CONNECT(graph_bt, "clicked", on_graph_bt_clicked, user_data);    
+       g_signal_connect(graph_bt, "clicked", G_CALLBACK(on_graph_bt_clicked), user_data);
 
 
 #ifdef USE_CONVERSATION_GRAPH
        graph_bt = gtk_button_new_with_label("Graph");
        gtk_container_add(GTK_CONTAINER(box4), graph_bt);
        gtk_widget_show(graph_bt);
-       SIGNAL_CONNECT(graph_bt, "clicked", on_graph_bt_clicked, user_data);
+       g_signal_connect(graph_bt, "clicked", G_CALLBACK(on_graph_bt_clicked), user_data);
 #endif
 
        next_bt = gtk_button_new_with_label("Next non-Ok");
        gtk_container_add(GTK_CONTAINER(box4), next_bt);
        gtk_widget_show(next_bt);
-       SIGNAL_CONNECT(next_bt, "clicked", on_next_bt_clicked, user_data);
+       g_signal_connect(next_bt, "clicked", G_CALLBACK(on_next_bt_clicked_list), user_data);
 
-       close_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE);
+       close_bt = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
        gtk_container_add(GTK_CONTAINER(box4), close_bt);
     GTK_WIDGET_SET_FLAGS(close_bt, GTK_CAN_DEFAULT);
        gtk_widget_show(close_bt);
     window_set_cancel_button(window, close_bt, window_cancel_button_cb);
 
-    SIGNAL_CONNECT(window, "delete_event", window_delete_event_cb, NULL);
-       SIGNAL_CONNECT(window, "destroy", on_destroy, user_data);
+    g_signal_connect(window, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
+       g_signal_connect(window, "destroy", G_CALLBACK(on_destroy), user_data);
 
     gtk_widget_show(window);
     window_present(window);
 
-       /* sort by column feature */
-       col_arrows_fwd = add_sort_by_column(window, clist_fwd, user_data);
-       col_arrows_rev = add_sort_by_column(window, clist_rev, user_data);
 
        /* some widget references need to be saved for outside use */
        user_data->dlg.window = window;
-       user_data->dlg.clist_fwd = GTK_CLIST(clist_fwd);
-       user_data->dlg.clist_rev = GTK_CLIST(clist_rev);
+       user_data->dlg.list_fwd = list_fwd;
+       user_data->dlg.list_rev = list_rev;
        user_data->dlg.label_stats_fwd = label_stats_fwd;
        user_data->dlg.label_stats_rev = label_stats_rev;
        user_data->dlg.notebook = notebook;
-       user_data->dlg.selected_clist = GTK_CLIST(clist_fwd);
-       user_data->dlg.selected_row = 0;
-       user_data->dlg.col_arrows_fwd = col_arrows_fwd;
-       user_data->dlg.col_arrows_rev = col_arrows_rev;
+       user_data->dlg.selected_list = list_fwd;
+       user_data->dlg.number_of_nok = 0;
+
+       /*
+        * select the initial row
+        */
+       gtk_widget_grab_focus(list_fwd);
+
 }
 
 
@@ -3507,7 +3457,7 @@ static gboolean process_node(proto_node *ptree_node, header_field_info *hfinform
                hfssrc = proto_registrar_get_byname(proto_field);
                if (hfssrc == NULL)
                        return FALSE;
-               for(ptree_node=ptree_node->first_child; ptree_node!=NULL; 
+               for(ptree_node=ptree_node->first_child; ptree_node!=NULL;
                                        ptree_node=ptree_node->next) {
                        finfo=PITEM_FINFO(ptree_node);
                        if (hfssrc==finfo->hfinfo) {
@@ -3516,11 +3466,13 @@ static gboolean process_node(proto_node *ptree_node, header_field_info *hfinform
                                        *p_result = ipv4_get_net_order_addr(ipv4);
                                }
                                else {
-                                       *p_result = fvalue_get_integer(&finfo->value);
+                                       *p_result = fvalue_get_uinteger(&finfo->value);
                                }
                                return TRUE;
                        }
                }
+               if(!ptree_node)
+                       return FALSE;
        }
 
        proto_sibling_node = ptree_node->next;
@@ -3553,10 +3505,6 @@ static gboolean get_int_value_from_proto_tree(proto_tree *protocol_tree,
 }
 
 
-/* XXX just copied from gtk/rpc_stat.c */
-void protect_thread_critical_region(void);
-void unprotect_thread_critical_region(void);
-
 /****************************************************************************/
 void rtp_analysis(
                address *ip_src_fwd,
@@ -3600,15 +3548,15 @@ void rtp_analysis(
        /*XXX: check for errors*/
        fd = create_tempfile(user_data->f_tempname, sizeof(user_data->f_tempname),
                "ether_rtp_f");
-       close(fd);
+       ws_close(fd);
        fd = create_tempfile(user_data->r_tempname, sizeof(user_data->r_tempname),
                "ether_rtp_r");
-       close(fd);
+       ws_close(fd);
        user_data->forward.saveinfo.fp = NULL;
        user_data->reversed.saveinfo.fp = NULL;
        user_data->dlg.save_voice_as_w = NULL;
        user_data->dlg.save_csv_as_w = NULL;
-        user_data->dlg.dialog_graph.window = NULL;
+    user_data->dlg.dialog_graph.window = NULL;
 
 #ifdef USE_CONVERSATION_GRAPH
        user_data->dlg.graph_window = NULL;
@@ -3652,7 +3600,7 @@ void rtp_analysis(
 
 /****************************************************************************/
 /* entry point from main menu */
-static void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_) 
+static void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
 {
        address ip_src_fwd;
        guint16 port_src_fwd;
@@ -3680,15 +3628,15 @@ static void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
        guint nfound;
 
        /* Try to compile the filter. */
-       strcpy(filter_text,"rtp && rtp.version && rtp.ssrc && (ip || ipv6)");
+       g_strlcpy(filter_text,"rtp && rtp.version && rtp.ssrc && (ip || ipv6)",sizeof(filter_text));
        if (!dfilter_compile(filter_text, &sfcode)) {
-               simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, dfilter_error_msg);
+               simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", dfilter_error_msg);
                return;
        }
        /* we load the current file into cf variable */
        cf = &cfile;
        fdata = cf->current_frame;
-       
+
        /* we are on the selected frame now */
        if (fdata == NULL)
                return; /* if we exit here it's an error */
@@ -3704,7 +3652,7 @@ static void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
        epan_dissect_prime_dfilter(edt, sfcode);
        epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
        frame_matched = dfilter_apply_edt(sfcode, edt);
-       
+
        /* if it is not an rtp frame, show the rtpstream dialog */
        frame_matched = dfilter_apply_edt(sfcode, edt);
        if (frame_matched != 1) {
@@ -3732,7 +3680,7 @@ static void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
                     "RTP Version != 2 isn't supported!");
                 return;
         }
-       
+
        /* now we need the SSRC value of the current frame */
        if (!get_int_value_from_proto_tree(edt->tree, "rtp", "rtp.ssrc", &ssrc_fwd)) {
                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
@@ -3793,7 +3741,7 @@ static void rtp_analysis_cb(GtkWidget *w _U_, gpointer data _U_)
 
 /****************************************************************************/
 static void
-rtp_analysis_init(const char *dummy _U_)
+rtp_analysis_init(const char *dummy _U_,void* userdata _U_)
 {
        rtp_analysis_cb(NULL, NULL);
 }
@@ -3802,7 +3750,7 @@ rtp_analysis_init(const char *dummy _U_)
 void
 register_tap_listener_rtp_analysis(void)
 {
-       register_stat_cmd_arg("rtp", rtp_analysis_init);
+       register_stat_cmd_arg("rtp", rtp_analysis_init,NULL);
 
        register_stat_menu_item("RTP/Stream Analysis...", REGISTER_STAT_GROUP_TELEPHONY,
            rtp_analysis_cb, NULL, NULL, NULL);