forked from osmocom/wireshark
From Francisco Alcoba
Flow Graphs for any protocol svn path=/trunk/; revision=14948
This commit is contained in:
parent
210deaf2cd
commit
b231e455c7
|
@ -121,6 +121,7 @@ ETHEREAL_TAP_SRC = \
|
|||
conversations_wlan.c \
|
||||
dcerpc_stat.c \
|
||||
fc_stat.c \
|
||||
flow_graph.c \
|
||||
gsm_a_stat.c \
|
||||
gsm_map_stat.c \
|
||||
gsm_map_summary.c \
|
||||
|
|
|
@ -0,0 +1,566 @@
|
|||
/* flow_graph.c
|
||||
* Allows to display a flow graph of the currently displayed packets
|
||||
*
|
||||
* Copyright 2004, Ericsson , Spain
|
||||
* By Francisco Alcoba <francisco.alcoba@ericsson.com>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "register.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "epan/filesystem.h"
|
||||
|
||||
#include "graph_analysis.h"
|
||||
#include "tap_menu.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "ui_util.h"
|
||||
#include "compat_macros.h"
|
||||
#include "gtkglobals.h"
|
||||
|
||||
#include "image/clist_ascend.xpm"
|
||||
#include "image/clist_descend.xpm"
|
||||
#include "simple_dialog.h"
|
||||
|
||||
#include <epan/to_str.h>
|
||||
#include <epan/tap.h>
|
||||
#include <epan/dissectors/packet-tcp.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define DISPLAYED 0
|
||||
#define ALL 1
|
||||
#define GENERAL 0
|
||||
#define TCP 1
|
||||
|
||||
static int type_of_packets = DISPLAYED;
|
||||
static int type_of_flow = GENERAL;
|
||||
|
||||
static int tap_identifier;
|
||||
static gboolean have_frame_tap_listener=FALSE;
|
||||
static gboolean have_tcp_tap_listener=FALSE;
|
||||
static graph_analysis_info_t *graph_analysis = NULL;
|
||||
static graph_analysis_data_t *graph_analysis_data;
|
||||
|
||||
static GtkWidget *flow_graph_dlg = NULL;
|
||||
|
||||
static GtkWidget *select_all_rb;
|
||||
static GtkWidget *select_displayed_rb;
|
||||
static GtkWidget *select_general_rb;
|
||||
static GtkWidget *select_tcp_rb;
|
||||
|
||||
void flow_graph_data_init(void);
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* free up memory and initialize the pointers */
|
||||
|
||||
void flow_graph_reset(void *ptr _U_)
|
||||
{
|
||||
|
||||
graph_analysis_item_t *graph_item;
|
||||
|
||||
GList* list;
|
||||
|
||||
if (graph_analysis !=NULL){
|
||||
|
||||
/* free the graph data items */
|
||||
list = g_list_first(graph_analysis->list);
|
||||
while (list)
|
||||
{
|
||||
graph_item = list->data;
|
||||
g_free(graph_item->frame_label);
|
||||
g_free(graph_item->comment);
|
||||
g_free(list->data);
|
||||
list = g_list_next(list);
|
||||
}
|
||||
g_list_free(graph_analysis->list);
|
||||
graph_analysis->nconv = 0;
|
||||
graph_analysis->list = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
void flow_graph_data_init(void) {
|
||||
graph_analysis = g_malloc(sizeof(graph_analysis_info_t));
|
||||
graph_analysis->nconv = 0;
|
||||
graph_analysis->list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX just copied from gtk/rpc_stat.c */
|
||||
void protect_thread_critical_region(void);
|
||||
void unprotect_thread_critical_region(void);
|
||||
|
||||
/****************************************************************************/
|
||||
void
|
||||
remove_tap_listener_flow_graph(void)
|
||||
{
|
||||
protect_thread_critical_region();
|
||||
remove_tap_listener(&(tap_identifier));
|
||||
unprotect_thread_critical_region();
|
||||
|
||||
have_frame_tap_listener=FALSE;
|
||||
have_tcp_tap_listener=FALSE;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* CALLBACKS */
|
||||
/****************************************************************************/
|
||||
static void
|
||||
flow_graph_on_destroy(GtkObject *object _U_, gpointer user_data _U_)
|
||||
{
|
||||
/* remove_tap_listeners */
|
||||
remove_tap_listener_flow_graph();
|
||||
|
||||
/* Clean up memory used by tap */
|
||||
flow_graph_reset(NULL);
|
||||
|
||||
/* Note that we no longer have a "Flow Graph" dialog box. */
|
||||
flow_graph_dlg = NULL;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
static void
|
||||
toggle_select_all(GtkWidget *widget _U_, gpointer user_data _U_)
|
||||
{
|
||||
/* is the button now active? */
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(select_all_rb))) {
|
||||
type_of_packets = ALL;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static void
|
||||
toggle_select_displayed(GtkWidget *widget _U_, gpointer user_data _U_)
|
||||
{
|
||||
/* is the button now active? */
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(select_displayed_rb))) {
|
||||
type_of_packets = DISPLAYED;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static void
|
||||
toggle_select_general(GtkWidget *widget _U_, gpointer user_data _U_)
|
||||
{
|
||||
/* is the button now active? */
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(select_general_rb))) {
|
||||
type_of_flow = GENERAL;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static void
|
||||
toggle_select_tcp(GtkWidget *widget _U_, gpointer user_data _U_)
|
||||
{
|
||||
/* is the button now active? */
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(select_tcp_rb))) {
|
||||
type_of_flow = TCP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Add a new frame into the graph */
|
||||
int flow_graph_frame_add_to_graph(packet_info *pinfo)
|
||||
{
|
||||
graph_analysis_item_t *gai;
|
||||
int i;
|
||||
|
||||
gai = g_malloc(sizeof(graph_analysis_item_t));
|
||||
gai->frame_num = pinfo->fd->num;
|
||||
gai->time= (double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000;
|
||||
COPY_ADDRESS(&(gai->src_addr),&(pinfo->src));
|
||||
COPY_ADDRESS(&(gai->dst_addr),&(pinfo->dst));
|
||||
gai->port_src=pinfo->srcport;
|
||||
gai->port_dst=pinfo->destport;
|
||||
gai->comment=NULL;
|
||||
gai->frame_label=NULL;
|
||||
|
||||
if (pinfo->cinfo->col_first[COL_INFO]>=0){
|
||||
|
||||
for (i = pinfo->cinfo->col_first[COL_INFO]; i <= pinfo->cinfo->col_last[COL_INFO]; i++) {
|
||||
if (pinfo->cinfo->fmt_matx[i][COL_INFO]) {
|
||||
if (gai->frame_label!=NULL){
|
||||
g_free(gai->frame_label);
|
||||
}
|
||||
gai->comment = g_strdup(pinfo->cinfo->col_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pinfo->cinfo->col_first[COL_PROTOCOL]>=0){
|
||||
|
||||
for (i = pinfo->cinfo->col_first[COL_PROTOCOL]; i <= pinfo->cinfo->col_last[COL_PROTOCOL]; i++) {
|
||||
if (pinfo->cinfo->fmt_matx[i][COL_PROTOCOL]) {
|
||||
if (gai->frame_label!=NULL){
|
||||
g_free(gai->frame_label);
|
||||
}
|
||||
gai->frame_label = g_strdup(pinfo->cinfo->col_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gai->line_style=1;
|
||||
gai->conv_num=0;
|
||||
gai->display=TRUE;
|
||||
|
||||
graph_analysis->list = g_list_append(graph_analysis->list, gai);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Add a new tcp frame into the graph */
|
||||
int flow_graph_tcp_add_to_graph(packet_info *pinfo, const struct tcpheader *tcph)
|
||||
{
|
||||
graph_analysis_item_t *gai;
|
||||
/* copied from packet-tcp */
|
||||
gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
|
||||
guint i, bpos;
|
||||
guint fpos = 0;
|
||||
gchar flags[64] = "<None>";
|
||||
|
||||
gai = g_malloc(sizeof(graph_analysis_item_t));
|
||||
gai->frame_num = pinfo->fd->num;
|
||||
gai->time= (double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000;
|
||||
COPY_ADDRESS(&(gai->src_addr),&(pinfo->src));
|
||||
COPY_ADDRESS(&(gai->dst_addr),&(pinfo->dst));
|
||||
gai->port_src=pinfo->srcport;
|
||||
gai->port_dst=pinfo->destport;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
bpos = 1 << i;
|
||||
if (tcph->th_flags & bpos) {
|
||||
if (fpos) {
|
||||
strcpy(&flags[fpos], ", ");
|
||||
fpos += 2;
|
||||
}
|
||||
strcpy(&flags[fpos], fstr[i]);
|
||||
fpos += 3;
|
||||
}
|
||||
}
|
||||
flags[fpos] = '\0';
|
||||
if ((tcph->th_have_seglen)&&(tcph->th_seglen!=0)){
|
||||
gai->frame_label = g_strdup_printf("%s - Len: %u",flags, tcph->th_seglen);
|
||||
}
|
||||
else{
|
||||
gai->frame_label = g_strdup(flags);
|
||||
}
|
||||
|
||||
gai->comment = g_strdup_printf("Seq = %i Ack = %i",tcph->th_seq, tcph->th_ack);
|
||||
|
||||
gai->line_style=1;
|
||||
gai->conv_num=0;
|
||||
gai->display=TRUE;
|
||||
|
||||
graph_analysis->list = g_list_append(graph_analysis->list, gai);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* whenever a frame packet is seen by the tap listener */
|
||||
static int
|
||||
flow_graph_frame_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *dummy _U_)
|
||||
{
|
||||
|
||||
if ((type_of_packets == ALL)||(pinfo->fd->flags.passed_dfilter==1)){
|
||||
flow_graph_frame_add_to_graph(pinfo);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* whenever a TCP packet is seen by the tap listener */
|
||||
static int
|
||||
flow_graph_tcp_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *tcp_info)
|
||||
{
|
||||
const struct tcpheader *tcph = tcp_info;
|
||||
|
||||
if ((type_of_packets == ALL)||(pinfo->fd->flags.passed_dfilter==1)){
|
||||
flow_graph_tcp_add_to_graph(pinfo,tcph);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void flow_graph_packet_draw(void *prs _U_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static void
|
||||
flow_graph_on_ok (GtkButton *button _U_,
|
||||
gpointer user_data _U_)
|
||||
{
|
||||
|
||||
if ((have_frame_tap_listener==TRUE)
|
||||
||(have_tcp_tap_listener==TRUE))
|
||||
{
|
||||
/* remove_tap_listeners */
|
||||
remove_tap_listener_flow_graph();
|
||||
}
|
||||
|
||||
/* Scan for displayed packets (redissect all packets) */
|
||||
|
||||
if (type_of_flow == GENERAL){
|
||||
/* Register the tap listener */
|
||||
|
||||
if(have_frame_tap_listener==FALSE)
|
||||
{
|
||||
/* don't register tap listener, if we have it already */
|
||||
register_tap_listener("frame", &tap_identifier, NULL,
|
||||
flow_graph_reset,
|
||||
flow_graph_frame_packet,
|
||||
flow_graph_packet_draw
|
||||
);
|
||||
have_frame_tap_listener=TRUE;
|
||||
}
|
||||
|
||||
cf_redissect_packets(&cfile);
|
||||
}
|
||||
else if (type_of_flow == TCP){
|
||||
/* Register the tap listener */
|
||||
|
||||
if(have_tcp_tap_listener==FALSE)
|
||||
{
|
||||
/* don't register tap listener, if we have it already */
|
||||
register_tap_listener("tcp", &tap_identifier, NULL,
|
||||
flow_graph_reset,
|
||||
flow_graph_tcp_packet,
|
||||
flow_graph_packet_draw
|
||||
);
|
||||
have_tcp_tap_listener=TRUE;
|
||||
}
|
||||
|
||||
cf_retap_packets(&cfile);
|
||||
}
|
||||
|
||||
if (graph_analysis_data->dlg.window != NULL){ /* if we still have a window */
|
||||
graph_analysis_update(graph_analysis_data); /* refresh it xxx */
|
||||
}
|
||||
else{
|
||||
graph_analysis_create(graph_analysis_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* INTERFACE */
|
||||
/****************************************************************************/
|
||||
|
||||
static void flow_graph_dlg_create (void)
|
||||
{
|
||||
|
||||
GtkWidget *flow_graph_dlg_w;
|
||||
GtkWidget *main_vb;
|
||||
GtkWidget *hbuttonbox;
|
||||
GtkWidget *bt_close, *bt_ok;
|
||||
#if 0
|
||||
GtkWidget *top_label = NULL;
|
||||
#endif
|
||||
GtkWidget *flow_type_fr, *range_fr, *range_tb, *flow_type_tb;
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
GtkAccelGroup *accel_group;
|
||||
#endif
|
||||
|
||||
|
||||
GtkTooltips *tooltips = gtk_tooltips_new();
|
||||
|
||||
flow_graph_dlg_w=window_new(GTK_WINDOW_TOPLEVEL, "Ethereal: Packet flow graph");
|
||||
|
||||
gtk_window_set_default_size(GTK_WINDOW(flow_graph_dlg_w), 350, 150);
|
||||
|
||||
main_vb = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(flow_graph_dlg_w), main_vb);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (main_vb), 12);
|
||||
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
/* Accelerator group for the accelerators (or, as they're called in
|
||||
Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
|
||||
Ctrl+<key> is an accelerator). */
|
||||
accel_group = gtk_accel_group_new();
|
||||
gtk_window_add_accel_group(GTK_WINDOW(main_vb), accel_group);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
top_label = gtk_label_new ("Choose packets to include in the graph");
|
||||
gtk_box_pack_start (GTK_BOX (main_vb), top_label, FALSE, FALSE, 8);
|
||||
#endif
|
||||
|
||||
gtk_widget_show(flow_graph_dlg_w);
|
||||
|
||||
/*** Packet range frame ***/
|
||||
range_fr = gtk_frame_new("Choose packets");
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), range_fr, FALSE, FALSE, 0);
|
||||
|
||||
range_tb = gtk_table_new(4, 4, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(range_tb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(range_fr), range_tb);
|
||||
|
||||
/* Process all packets */
|
||||
select_all_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL, "_All packets", accel_group);
|
||||
gtk_tooltips_set_tip (tooltips, select_all_rb,
|
||||
("Process all packets"), NULL);
|
||||
SIGNAL_CONNECT(select_all_rb, "toggled", toggle_select_all, NULL);
|
||||
gtk_table_attach_defaults(GTK_TABLE(range_tb), select_all_rb, 0, 1, 0, 1);
|
||||
if (type_of_packets == ALL) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_all_rb),TRUE);
|
||||
}
|
||||
gtk_widget_show(select_all_rb);
|
||||
|
||||
/* Process displayed packets */
|
||||
select_displayed_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(select_all_rb, "_Displayed packets", accel_group);
|
||||
gtk_tooltips_set_tip (tooltips, select_displayed_rb,
|
||||
("Process displayed packets"), NULL);
|
||||
SIGNAL_CONNECT(select_displayed_rb, "toggled", toggle_select_displayed, NULL);
|
||||
gtk_table_attach_defaults(GTK_TABLE(range_tb), select_displayed_rb, 1, 2, 0, 1);
|
||||
if (type_of_packets == DISPLAYED) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_displayed_rb),TRUE);
|
||||
}
|
||||
gtk_widget_show(select_displayed_rb);
|
||||
|
||||
gtk_widget_show(range_tb);
|
||||
|
||||
gtk_widget_show(range_fr);
|
||||
|
||||
/*** Flow type frame ***/
|
||||
flow_type_fr = gtk_frame_new("Choose flow type");
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), flow_type_fr, FALSE, FALSE, 0);
|
||||
|
||||
flow_type_tb = gtk_table_new(4, 4, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(flow_type_tb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(flow_type_fr), flow_type_tb);
|
||||
|
||||
/* General information */
|
||||
select_general_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL, "_General flow", accel_group);
|
||||
gtk_tooltips_set_tip (tooltips, select_general_rb,
|
||||
("Show all packets, with general information"), NULL);
|
||||
SIGNAL_CONNECT(select_general_rb, "toggled", toggle_select_general, NULL);
|
||||
gtk_table_attach_defaults(GTK_TABLE(flow_type_tb), select_general_rb, 0, 1, 0, 1);
|
||||
if (type_of_flow == GENERAL) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_general_rb),TRUE);
|
||||
}
|
||||
gtk_widget_show(select_general_rb);
|
||||
|
||||
/* TCP specific information */
|
||||
select_tcp_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(select_general_rb, "_TCP flow", accel_group);
|
||||
gtk_tooltips_set_tip (tooltips, select_tcp_rb,
|
||||
("Show only TCP packets, with TCP specific information"), NULL);
|
||||
SIGNAL_CONNECT(select_tcp_rb, "toggled", toggle_select_tcp, NULL);
|
||||
gtk_table_attach_defaults(GTK_TABLE(flow_type_tb), select_tcp_rb, 1, 2, 0, 1);
|
||||
if (type_of_flow == TCP) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_tcp_rb),TRUE);
|
||||
}
|
||||
|
||||
gtk_widget_show(select_tcp_rb);
|
||||
|
||||
gtk_widget_show(flow_type_tb);
|
||||
gtk_widget_show(flow_type_fr);
|
||||
|
||||
/* button row */
|
||||
hbuttonbox = gtk_hbutton_box_new ();
|
||||
gtk_box_pack_start (GTK_BOX (main_vb), hbuttonbox, FALSE, FALSE, 0);
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_SPREAD);
|
||||
gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox), 30);
|
||||
|
||||
bt_ok = BUTTON_NEW_FROM_STOCK(GTK_STOCK_OK);
|
||||
gtk_container_add(GTK_CONTAINER(hbuttonbox), bt_ok);
|
||||
gtk_tooltips_set_tip (tooltips, bt_ok, "Show the flow graph", NULL);
|
||||
SIGNAL_CONNECT(bt_ok, "clicked", flow_graph_on_ok, NULL);
|
||||
gtk_widget_show(bt_ok);
|
||||
|
||||
bt_close = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE);
|
||||
gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_close);
|
||||
GTK_WIDGET_SET_FLAGS(bt_close, GTK_CAN_DEFAULT);
|
||||
gtk_tooltips_set_tip (tooltips, bt_close, "Close this dialog", NULL);
|
||||
window_set_cancel_button(flow_graph_dlg_w, bt_close, window_cancel_button_cb);
|
||||
|
||||
SIGNAL_CONNECT(flow_graph_dlg_w, "delete_event", window_delete_event_cb, NULL);
|
||||
SIGNAL_CONNECT(flow_graph_dlg_w, "destroy", flow_graph_on_destroy, NULL);
|
||||
|
||||
gtk_widget_show_all(flow_graph_dlg_w);
|
||||
window_present(flow_graph_dlg_w);
|
||||
|
||||
flow_graph_dlg = flow_graph_dlg_w;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* PUBLIC */
|
||||
/****************************************************************************/
|
||||
|
||||
/* init function for tap */
|
||||
static void
|
||||
flow_graph_init_tap(char *dummy _U_)
|
||||
{
|
||||
|
||||
/* initialize graph items store */
|
||||
flow_graph_data_init();
|
||||
|
||||
/* init the Graph Analysys */
|
||||
graph_analysis_data = graph_analysis_init();
|
||||
graph_analysis_data->graph_info = graph_analysis;
|
||||
|
||||
/* create dialog box if necessary */
|
||||
if (flow_graph_dlg == NULL) {
|
||||
flow_graph_dlg_create();
|
||||
} else {
|
||||
/* There's already a dialog box; reactivate it. */
|
||||
reactivate_window(flow_graph_dlg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* entry point when called via the GTK menu */
|
||||
void flow_graph_launch(GtkWidget *w _U_, gpointer data _U_)
|
||||
{
|
||||
flow_graph_init_tap("");
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
void
|
||||
register_tap_listener_flow_graph(void)
|
||||
{
|
||||
register_tap_listener_cmd_arg("flow_graph",flow_graph_init_tap);
|
||||
register_tap_menu_item("Flow graph", REGISTER_TAP_GROUP_NONE,
|
||||
flow_graph_launch, NULL, NULL, NULL);
|
||||
|
||||
}
|
||||
|
|
@ -90,9 +90,12 @@ static GtkWidget *save_to_file_w = NULL;
|
|||
#define TIME_WIDTH 50
|
||||
|
||||
#define NODE_CHARS_WIDTH 20
|
||||
#define CONV_TIME_HEADER "Conv.| Time "
|
||||
#define EMPTY_HEADER " | "
|
||||
#define HEADER_LENGTH 16
|
||||
#define CONV_TIME_HEADER "Conv.| Time "
|
||||
#define TIME_HEADER "|Time "
|
||||
#define CONV_TIME_EMPTY_HEADER " | "
|
||||
#define TIME_EMPTY_HEADER "| "
|
||||
#define CONV_TIME_HEADER_LENGTH 16
|
||||
#define TIME_HEADER_LENGTH 10
|
||||
|
||||
/****************************************************************************/
|
||||
/* Reset the user_data structure */
|
||||
|
@ -156,7 +159,6 @@ static void graph_analysis_init_dlg(graph_analysis_data_t* user_data)
|
|||
/****************************************************************************/
|
||||
/* CALLBACKS */
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* close the dialog window and remove the tap listener */
|
||||
static void on_destroy(GtkWidget *win _U_, graph_analysis_data_t *user_data _U_)
|
||||
|
@ -172,7 +174,6 @@ static void on_destroy(GtkWidget *win _U_, graph_analysis_data_t *user_data _U_)
|
|||
user_data->dlg.window = NULL;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
#if 0
|
||||
static void dialog_graph_set_title(graph_analysis_data_t* user_data)
|
||||
|
@ -208,8 +209,10 @@ static void draw_arrow(GdkDrawable *pixmap, GdkGC *gc, gint x, gint y, gboolean
|
|||
arrow_point[2].x = x;
|
||||
arrow_point[2].y = y+HEIGHT_ARROW/2;;
|
||||
|
||||
gdk_draw_polygon(pixmap, gc, TRUE,
|
||||
arrow_point, 3);
|
||||
if (GDK_IS_DRAWABLE(pixmap)) {
|
||||
gdk_draw_polygon(pixmap, gc, TRUE,
|
||||
arrow_point, 3);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -270,13 +273,15 @@ static void overwrite (char *string, char *text_to_insert, guint32 p1, guint32 p
|
|||
gboolean dialog_graph_dump_to_file(graph_analysis_data_t* user_data)
|
||||
{
|
||||
guint32 i, first_node, display_items, display_nodes;
|
||||
guint32 start_position, end_position, item_width;
|
||||
guint32 start_position, end_position, item_width, header_length;
|
||||
guint32 current_item;
|
||||
graph_analysis_item_t *gai;
|
||||
guint16 old_conv_num = 0;
|
||||
|
||||
guint16 first_conv_num;
|
||||
gboolean several_convs = FALSE;
|
||||
gboolean first_packet = TRUE;
|
||||
|
||||
char label_string[MAX_COMMENT];
|
||||
char *empty_line,* separator_line,*tmp_str, *tmp_str2;
|
||||
char *empty_line,* separator_line,*tmp_str, *tmp_str2, *empty_header;
|
||||
char src_port[8],dst_port[8];
|
||||
|
||||
GList* list;
|
||||
|
@ -302,6 +307,13 @@ gboolean dialog_graph_dump_to_file(graph_analysis_data_t* user_data)
|
|||
user_data->dlg.items[current_item].port_dst = gai->port_dst;
|
||||
user_data->dlg.items[current_item].frame_label = gai->frame_label;
|
||||
user_data->dlg.items[current_item].comment = gai->comment;
|
||||
if (first_packet){
|
||||
first_conv_num = gai->conv_num;
|
||||
first_packet=FALSE;
|
||||
}
|
||||
if (user_data->dlg.items[current_item].conv_num != first_conv_num){
|
||||
several_convs = TRUE;
|
||||
}
|
||||
user_data->dlg.items[current_item].conv_num = gai->conv_num;
|
||||
user_data->dlg.items[current_item].src_node = gai->src_node;
|
||||
user_data->dlg.items[current_item].dst_node = gai->dst_node;
|
||||
|
@ -322,7 +334,17 @@ gboolean dialog_graph_dump_to_file(graph_analysis_data_t* user_data)
|
|||
|
||||
/* Write the conv. and time headers */
|
||||
|
||||
fprintf (of, CONV_TIME_HEADER);
|
||||
if (several_convs){
|
||||
fprintf (of, CONV_TIME_HEADER);
|
||||
empty_header = g_strdup(CONV_TIME_EMPTY_HEADER);
|
||||
header_length=CONV_TIME_HEADER_LENGTH;
|
||||
}
|
||||
else{
|
||||
fprintf (of, TIME_HEADER);
|
||||
empty_header = g_strdup(TIME_EMPTY_HEADER);
|
||||
header_length=TIME_HEADER_LENGTH;
|
||||
}
|
||||
|
||||
empty_line = g_strdup("");
|
||||
|
||||
|
||||
|
@ -345,9 +367,9 @@ gboolean dialog_graph_dump_to_file(graph_analysis_data_t* user_data)
|
|||
empty_line = g_strdup_printf("%s|",tmp_str);
|
||||
g_free(tmp_str);
|
||||
|
||||
separator_line = g_malloc(strlen(empty_line)+HEADER_LENGTH+1);
|
||||
separator_line = g_malloc(strlen(empty_line)+header_length+1);
|
||||
separator_line[0]='\0';
|
||||
enlarge_string(separator_line,strlen(empty_line)+HEADER_LENGTH,'-');
|
||||
enlarge_string(separator_line,strlen(empty_line)+header_length,'-');
|
||||
separator_line[strlen(separator_line)-1]='\n';
|
||||
|
||||
|
||||
|
@ -375,19 +397,21 @@ gboolean dialog_graph_dump_to_file(graph_analysis_data_t* user_data)
|
|||
}
|
||||
|
||||
/* separator between conversations */
|
||||
if (user_data->dlg.items[current_item].conv_num != old_conv_num){
|
||||
if (user_data->dlg.items[current_item].conv_num != first_conv_num){
|
||||
fprintf(of,separator_line);
|
||||
old_conv_num=user_data->dlg.items[current_item].conv_num;
|
||||
first_conv_num=user_data->dlg.items[current_item].conv_num;
|
||||
}
|
||||
|
||||
/* write the conversation number */
|
||||
g_snprintf(label_string, 5, "%i", user_data->dlg.items[current_item].conv_num);
|
||||
enlarge_string(label_string,5,' ');
|
||||
fprintf(of,"%s",label_string);
|
||||
if (several_convs){
|
||||
g_snprintf(label_string, 5, "%i", user_data->dlg.items[current_item].conv_num);
|
||||
enlarge_string(label_string,5,' ');
|
||||
fprintf(of,"%s",label_string);
|
||||
}
|
||||
|
||||
/* write the time */
|
||||
g_snprintf(label_string, 11, "|%.3f", user_data->dlg.items[current_item].time);
|
||||
enlarge_string(label_string,11,' ');
|
||||
g_snprintf(label_string, 10, "|%.3f", user_data->dlg.items[current_item].time);
|
||||
enlarge_string(label_string,10,' ');
|
||||
fprintf(of,"%s",label_string);
|
||||
|
||||
/* write the frame label */
|
||||
|
@ -403,8 +427,8 @@ gboolean dialog_graph_dump_to_file(graph_analysis_data_t* user_data)
|
|||
g_snprintf(label_string, MAX_COMMENT, "%s", user_data->dlg.items[current_item].comment);
|
||||
fprintf(of,"%s\n",label_string);
|
||||
|
||||
/* write draw the arrow and frame label*/
|
||||
fprintf(of,EMPTY_HEADER);
|
||||
/* write the arrow and frame label*/
|
||||
fprintf(of,empty_header);
|
||||
|
||||
tmp_str = g_strdup(empty_line);
|
||||
|
||||
|
@ -574,6 +598,10 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
guint32 top_y_border;
|
||||
guint32 bottom_y_border;
|
||||
graph_analysis_item_t *gai;
|
||||
guint16 first_conv_num;
|
||||
gboolean several_convs = FALSE;
|
||||
gboolean first_packet = TRUE;
|
||||
|
||||
GdkGC *frame_fg_color;
|
||||
GdkGC *frame_bg_color;
|
||||
GdkGC *div_line_color;
|
||||
|
@ -605,27 +633,29 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
user_data->dlg.needs_redraw=FALSE;
|
||||
|
||||
/* Clear out old plt */
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_time,
|
||||
user_data->dlg.draw_area_time->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area_time->allocation.width,
|
||||
user_data->dlg.draw_area_time->allocation.height);
|
||||
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap,
|
||||
user_data->dlg.draw_area->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area->allocation.width,
|
||||
user_data->dlg.draw_area->allocation.height);
|
||||
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_comments,
|
||||
user_data->dlg.draw_area->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area_comments->allocation.width,
|
||||
user_data->dlg.draw_area_comments->allocation.height);
|
||||
|
||||
if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_time) )
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_time,
|
||||
user_data->dlg.draw_area_time->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area_time->allocation.width,
|
||||
user_data->dlg.draw_area_time->allocation.height);
|
||||
|
||||
if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap) )
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap,
|
||||
user_data->dlg.draw_area->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area->allocation.width,
|
||||
user_data->dlg.draw_area->allocation.height);
|
||||
|
||||
if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments) )
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_comments,
|
||||
user_data->dlg.draw_area->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area_comments->allocation.width,
|
||||
user_data->dlg.draw_area_comments->allocation.height);
|
||||
|
||||
/* Calculate the y border */
|
||||
top_y_border=TOP_Y_BORDER; /* to display the node address */
|
||||
|
@ -660,6 +690,16 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
user_data->dlg.items[current_item].frame_label = gai->frame_label;
|
||||
user_data->dlg.items[current_item].comment = gai->comment;
|
||||
user_data->dlg.items[current_item].conv_num = gai->conv_num;
|
||||
|
||||
if (first_packet){
|
||||
first_conv_num = gai->conv_num;
|
||||
first_packet=FALSE;
|
||||
}
|
||||
|
||||
if (user_data->dlg.items[current_item].conv_num != first_conv_num){
|
||||
several_convs = TRUE;
|
||||
}
|
||||
|
||||
user_data->dlg.items[current_item].src_node = gai->src_node;
|
||||
user_data->dlg.items[current_item].dst_node = gai->dst_node;
|
||||
user_data->dlg.items[current_item].line_style = gai->line_style;
|
||||
|
@ -720,31 +760,34 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
draw_width=user_data->dlg.pixmap_width-right_x_border-left_x_border;
|
||||
|
||||
/* Paint time title background */
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_time,
|
||||
user_data->dlg.draw_area_time->style->bg_gc[2],
|
||||
TRUE,
|
||||
0,
|
||||
0,
|
||||
user_data->dlg.draw_area_time->allocation.width,
|
||||
top_y_border);
|
||||
if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_time) )
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_time,
|
||||
user_data->dlg.draw_area_time->style->bg_gc[2],
|
||||
TRUE,
|
||||
0,
|
||||
0,
|
||||
user_data->dlg.draw_area_time->allocation.width,
|
||||
top_y_border);
|
||||
/* Paint main title background */
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap,
|
||||
user_data->dlg.draw_area->style->bg_gc[2],
|
||||
TRUE,
|
||||
0,
|
||||
0,
|
||||
user_data->dlg.draw_area->allocation.width,
|
||||
top_y_border);
|
||||
if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap) )
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap,
|
||||
user_data->dlg.draw_area->style->bg_gc[2],
|
||||
TRUE,
|
||||
0,
|
||||
0,
|
||||
user_data->dlg.draw_area->allocation.width,
|
||||
top_y_border);
|
||||
/* Paint main comment background */
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_comments,
|
||||
user_data->dlg.draw_area_comments->style->bg_gc[2],
|
||||
TRUE,
|
||||
0,
|
||||
0,
|
||||
user_data->dlg.draw_area_comments->allocation.width,
|
||||
top_y_border);
|
||||
|
||||
|
||||
if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments) )
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_comments,
|
||||
user_data->dlg.draw_area_comments->style->bg_gc[2],
|
||||
TRUE,
|
||||
0,
|
||||
0,
|
||||
user_data->dlg.draw_area_comments->allocation.width,
|
||||
top_y_border);
|
||||
|
||||
|
||||
/* Draw the word "Time" on top of time column */
|
||||
g_snprintf(label_string, label_width, "%s", "Time");
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
|
@ -759,11 +802,13 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
#else
|
||||
pango_layout_set_text(layout, label_string, -1);
|
||||
pango_layout_get_pixel_size(layout, &label_width, &label_height);
|
||||
gdk_draw_layout(user_data->dlg.pixmap_time,
|
||||
user_data->dlg.draw_area_time->style->black_gc,
|
||||
left_x_border,
|
||||
top_y_border/2-label_height/2,
|
||||
layout);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_time)) {
|
||||
gdk_draw_layout(user_data->dlg.pixmap_time,
|
||||
user_data->dlg.draw_area_time->style->black_gc,
|
||||
left_x_border,
|
||||
top_y_border/2-label_height/2,
|
||||
layout);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Draw the word "Comment" on top of comment column */
|
||||
|
@ -780,31 +825,34 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
#else
|
||||
pango_layout_set_text(layout, label_string, -1);
|
||||
pango_layout_get_pixel_size(layout, &label_width, &label_height);
|
||||
gdk_draw_layout(user_data->dlg.pixmap_comments,
|
||||
user_data->dlg.draw_area_comments->style->black_gc,
|
||||
MAX_COMMENT/2-label_width/2,
|
||||
top_y_border/2-label_height/2,
|
||||
layout);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments)) {
|
||||
gdk_draw_layout(user_data->dlg.pixmap_comments,
|
||||
user_data->dlg.draw_area_comments->style->black_gc,
|
||||
MAX_COMMENT/2-label_width/2,
|
||||
top_y_border/2-label_height/2,
|
||||
layout);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Paint the background items */
|
||||
/* Paint the background items */
|
||||
for (current_item=0; current_item<display_items; current_item++){
|
||||
/*select the color. if it is the selected item select blue color */
|
||||
if ( current_item+first_item == user_data->dlg.selected_item )
|
||||
frame_bg_color = user_data->dlg.bg_gc[0];
|
||||
else
|
||||
frame_bg_color = user_data->dlg.bg_gc[1+user_data->dlg.items[current_item].conv_num%MAX_NUM_COL_CONV];
|
||||
|
||||
|
||||
/* Paint background */
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap,
|
||||
frame_bg_color,
|
||||
TRUE,
|
||||
left_x_border,
|
||||
top_y_border+current_item*ITEM_HEIGHT,
|
||||
draw_width,
|
||||
ITEM_HEIGHT);
|
||||
if (several_convs && GDK_IS_DRAWABLE(user_data->dlg.pixmap)) {
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap,
|
||||
frame_bg_color,
|
||||
TRUE,
|
||||
left_x_border,
|
||||
top_y_border+current_item*ITEM_HEIGHT,
|
||||
draw_width,
|
||||
ITEM_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the node names on top and the division lines */
|
||||
for (i=0; i<user_data->num_nodes; i++){
|
||||
/* print the node identifiers */
|
||||
|
@ -823,19 +871,23 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
#else
|
||||
pango_layout_set_text(layout, label_string, -1);
|
||||
pango_layout_get_pixel_size(layout, &label_width, &label_height);
|
||||
gdk_draw_layout(user_data->dlg.pixmap,
|
||||
user_data->dlg.draw_area->style->black_gc,
|
||||
left_x_border+NODE_WIDTH/2-label_width/2+NODE_WIDTH*i,
|
||||
top_y_border/2-label_height/2,
|
||||
layout);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap)) {
|
||||
gdk_draw_layout(user_data->dlg.pixmap,
|
||||
user_data->dlg.draw_area->style->black_gc,
|
||||
left_x_border+NODE_WIDTH/2-label_width/2+NODE_WIDTH*i,
|
||||
top_y_border/2-label_height/2,
|
||||
layout);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* draw the node division lines */
|
||||
gdk_draw_line(user_data->dlg.pixmap, user_data->dlg.div_line_gc[0],
|
||||
left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
|
||||
top_y_border,
|
||||
left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
|
||||
user_data->dlg.pixmap_height-bottom_y_border);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap) ) {
|
||||
gdk_draw_line(user_data->dlg.pixmap, user_data->dlg.div_line_gc[0],
|
||||
left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
|
||||
top_y_border,
|
||||
left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
|
||||
user_data->dlg.pixmap_height-bottom_y_border);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -855,11 +907,13 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
#else
|
||||
pango_layout_set_text(layout, label_string, -1);
|
||||
pango_layout_get_pixel_size(layout, &label_width, &label_height);
|
||||
gdk_draw_layout(user_data->dlg.pixmap_time,
|
||||
user_data->dlg.draw_area->style->black_gc,
|
||||
3,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
|
||||
layout);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_time)) {
|
||||
gdk_draw_layout(user_data->dlg.pixmap_time,
|
||||
user_data->dlg.draw_area->style->black_gc,
|
||||
3,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
|
||||
layout);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*draw the comments */
|
||||
|
@ -876,11 +930,13 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
#else
|
||||
pango_layout_set_text(small_layout, label_string, -1);
|
||||
pango_layout_get_pixel_size(small_layout, &label_width, &label_height);
|
||||
gdk_draw_layout(user_data->dlg.pixmap_comments,
|
||||
user_data->dlg.draw_area->style->black_gc,
|
||||
2,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
|
||||
small_layout);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments)) {
|
||||
gdk_draw_layout(user_data->dlg.pixmap_comments,
|
||||
user_data->dlg.draw_area->style->black_gc,
|
||||
2,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
|
||||
small_layout);
|
||||
}
|
||||
#endif
|
||||
/* select colors */
|
||||
if ( current_item+first_item == user_data->dlg.selected_item ){
|
||||
|
@ -894,14 +950,16 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
start_arrow = left_x_border+(user_data->dlg.items[current_item].src_node)*NODE_WIDTH+NODE_WIDTH/2;
|
||||
end_arrow = left_x_border+(user_data->dlg.items[current_item].dst_node)*NODE_WIDTH+NODE_WIDTH/2;
|
||||
|
||||
gdk_draw_line(user_data->dlg.pixmap, frame_fg_color,
|
||||
start_arrow,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-7,
|
||||
end_arrow,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-7);
|
||||
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap) ) {
|
||||
gdk_draw_line(user_data->dlg.pixmap, frame_fg_color,
|
||||
start_arrow,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-7,
|
||||
end_arrow,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-7);
|
||||
}
|
||||
|
||||
/* draw the additional line when line style is 2 pixels width */
|
||||
if (user_data->dlg.items[current_item].line_style == 2){
|
||||
if (user_data->dlg.items[current_item].line_style == 2 && GDK_IS_DRAWABLE(user_data->dlg.pixmap)){
|
||||
gdk_draw_line(user_data->dlg.pixmap, frame_fg_color,
|
||||
start_arrow,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-6,
|
||||
|
@ -946,11 +1004,13 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2+label_height/4-3,
|
||||
label_string);
|
||||
#else
|
||||
gdk_draw_layout(user_data->dlg.pixmap,
|
||||
frame_fg_color,
|
||||
label_x - label_width/2,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2-3,
|
||||
big_layout);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap)) {
|
||||
gdk_draw_layout(user_data->dlg.pixmap,
|
||||
frame_fg_color,
|
||||
label_x - label_width/2,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2-3,
|
||||
big_layout);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -977,11 +1037,13 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2+label_height/4-2,
|
||||
label_string);
|
||||
#else
|
||||
gdk_draw_layout(user_data->dlg.pixmap,
|
||||
div_line_color,
|
||||
src_port_x,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2-label_height/2-2,
|
||||
small_layout);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap)) {
|
||||
gdk_draw_layout(user_data->dlg.pixmap,
|
||||
div_line_color,
|
||||
src_port_x,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2-label_height/2-2,
|
||||
small_layout);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* draw the destination port number */
|
||||
|
@ -1007,20 +1069,24 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2+label_height/4-2,
|
||||
label_string);
|
||||
#else
|
||||
gdk_draw_layout(user_data->dlg.pixmap,
|
||||
div_line_color,
|
||||
dst_port_x,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2-label_height/2-2,
|
||||
small_layout);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap)) {
|
||||
gdk_draw_layout(user_data->dlg.pixmap,
|
||||
div_line_color,
|
||||
dst_port_x,
|
||||
top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2-label_height/2-2,
|
||||
small_layout);
|
||||
}
|
||||
#endif
|
||||
/* draw the div line of the selected item with soft gray*/
|
||||
if ( current_item+first_item == user_data->dlg.selected_item )
|
||||
for (i=0; i<user_data->num_nodes; i++){
|
||||
gdk_draw_line(user_data->dlg.pixmap, user_data->dlg.div_line_gc[1],
|
||||
left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
|
||||
(user_data->dlg.selected_item-first_item)*ITEM_HEIGHT+TOP_Y_BORDER,
|
||||
left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
|
||||
(user_data->dlg.selected_item-first_item)*ITEM_HEIGHT+TOP_Y_BORDER+ITEM_HEIGHT);
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.pixmap) ) {
|
||||
gdk_draw_line(user_data->dlg.pixmap, user_data->dlg.div_line_gc[1],
|
||||
left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
|
||||
(user_data->dlg.selected_item-first_item)*ITEM_HEIGHT+TOP_Y_BORDER,
|
||||
left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
|
||||
(user_data->dlg.selected_item-first_item)*ITEM_HEIGHT+TOP_Y_BORDER+ITEM_HEIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1028,30 +1094,33 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data)
|
|||
#if GTK_MAJOR_VERSION >= 2
|
||||
g_object_unref(G_OBJECT(layout));
|
||||
#endif
|
||||
|
||||
/* refresh the draw areas */
|
||||
gdk_draw_pixmap(user_data->dlg.draw_area_time->window,
|
||||
user_data->dlg.draw_area_time->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_time)],
|
||||
user_data->dlg.pixmap_time,
|
||||
0, 0,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area_time->allocation.width, user_data->dlg.draw_area_time->allocation.height);
|
||||
|
||||
gdk_draw_pixmap(user_data->dlg.draw_area->window,
|
||||
user_data->dlg.draw_area->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area)],
|
||||
user_data->dlg.pixmap,
|
||||
0, 0,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area->allocation.width, user_data->dlg.draw_area->allocation.height);
|
||||
|
||||
gdk_draw_pixmap(user_data->dlg.draw_area_comments->window,
|
||||
user_data->dlg.draw_area_comments->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_comments)],
|
||||
user_data->dlg.pixmap_comments,
|
||||
0, 0,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area_comments->allocation.width, user_data->dlg.draw_area_comments->allocation.height);
|
||||
|
||||
/* update the v_scrollbar */
|
||||
|
||||
/* refresh the draw areas */
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_time->window) )
|
||||
gdk_draw_pixmap(user_data->dlg.draw_area_time->window,
|
||||
user_data->dlg.draw_area_time->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_time)],
|
||||
user_data->dlg.pixmap_time,
|
||||
0, 0,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area_time->allocation.width, user_data->dlg.draw_area_time->allocation.height);
|
||||
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.draw_area->window) )
|
||||
gdk_draw_pixmap(user_data->dlg.draw_area->window,
|
||||
user_data->dlg.draw_area->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area)],
|
||||
user_data->dlg.pixmap,
|
||||
0, 0,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area->allocation.width, user_data->dlg.draw_area->allocation.height);
|
||||
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_comments->window) )
|
||||
gdk_draw_pixmap(user_data->dlg.draw_area_comments->window,
|
||||
user_data->dlg.draw_area_comments->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_comments)],
|
||||
user_data->dlg.pixmap_comments,
|
||||
0, 0,
|
||||
0, 0,
|
||||
user_data->dlg.draw_area_comments->allocation.width, user_data->dlg.draw_area_comments->allocation.height);
|
||||
|
||||
/* update the v_scrollbar */
|
||||
user_data->dlg.v_scrollbar_adjustment->upper=(gfloat) user_data->num_items-1;
|
||||
user_data->dlg.v_scrollbar_adjustment->step_increment=1;
|
||||
user_data->dlg.v_scrollbar_adjustment->page_increment=(gfloat) (last_item-first_item);
|
||||
|
@ -1087,7 +1156,7 @@ static gint button_press_event(GtkWidget *widget, GdkEventButton *event _U_)
|
|||
|
||||
user_data->dlg.needs_redraw=TRUE;
|
||||
dialog_graph_draw(user_data);
|
||||
|
||||
|
||||
cf_goto_frame(&cfile, user_data->dlg.items[item].frame_num);
|
||||
|
||||
return TRUE;
|
||||
|
@ -1175,7 +1244,8 @@ static gint expose_event(GtkWidget *widget, GdkEventExpose *event)
|
|||
}
|
||||
|
||||
|
||||
gdk_draw_pixmap(widget->window,
|
||||
if (GDK_IS_DRAWABLE(widget->window) )
|
||||
gdk_draw_pixmap(widget->window,
|
||||
widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
|
||||
user_data->dlg.pixmap,
|
||||
event->area.x, event->area.y,
|
||||
|
@ -1196,7 +1266,8 @@ static gint expose_event_comments(GtkWidget *widget, GdkEventExpose *event)
|
|||
}
|
||||
|
||||
|
||||
gdk_draw_pixmap(widget->window,
|
||||
if (GDK_IS_DRAWABLE(widget->window) )
|
||||
gdk_draw_pixmap(widget->window,
|
||||
widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
|
||||
user_data->dlg.pixmap_comments,
|
||||
event->area.x, event->area.y,
|
||||
|
@ -1217,7 +1288,8 @@ static gint expose_event_time(GtkWidget *widget, GdkEventExpose *event)
|
|||
}
|
||||
|
||||
|
||||
gdk_draw_pixmap(widget->window,
|
||||
if (GDK_IS_DRAWABLE(widget->window) )
|
||||
gdk_draw_pixmap(widget->window,
|
||||
widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
|
||||
user_data->dlg.pixmap_time,
|
||||
event->area.x, event->area.y,
|
||||
|
@ -1271,7 +1343,8 @@ static gint configure_event(GtkWidget *widget, GdkEventConfigure *event _U_)
|
|||
-1);
|
||||
user_data->dlg.pixmap_height=widget->allocation.height;
|
||||
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap,
|
||||
if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap) )
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap,
|
||||
widget->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
|
@ -1332,12 +1405,13 @@ static gint configure_event_comments(GtkWidget *widget, GdkEventConfigure *event
|
|||
widget->allocation.height,
|
||||
-1);
|
||||
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_comments,
|
||||
widget->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
widget->allocation.width,
|
||||
widget->allocation.height);
|
||||
if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap) )
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_comments,
|
||||
widget->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
widget->allocation.width,
|
||||
widget->allocation.height);
|
||||
|
||||
dialog_graph_redraw(user_data);
|
||||
return TRUE;
|
||||
|
@ -1364,12 +1438,13 @@ static gint configure_event_time(GtkWidget *widget, GdkEventConfigure *event _U_
|
|||
widget->allocation.height,
|
||||
-1);
|
||||
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_time,
|
||||
widget->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
widget->allocation.width,
|
||||
widget->allocation.height);
|
||||
if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_time) )
|
||||
gdk_draw_rectangle(user_data->dlg.pixmap_time,
|
||||
widget->style->white_gc,
|
||||
TRUE,
|
||||
0, 0,
|
||||
widget->allocation.width,
|
||||
widget->allocation.height);
|
||||
|
||||
dialog_graph_redraw(user_data);
|
||||
return TRUE;
|
||||
|
@ -1388,7 +1463,8 @@ static gint pane_callback(GtkWidget *widget, GParamSpec *pspec, gpointer data)
|
|||
else if (gtk_paned_get_position(GTK_PANED(user_data->dlg.hpane)) < NODE_WIDTH*2)
|
||||
gtk_paned_set_position(GTK_PANED(user_data->dlg.hpane), NODE_WIDTH*2);
|
||||
/* repaint the comment area because when moving the pane position thre are times that the expose_event_comments is not called */
|
||||
gdk_draw_pixmap(user_data->dlg.draw_area_comments->window,
|
||||
if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_comments->window) )
|
||||
gdk_draw_pixmap(user_data->dlg.draw_area_comments->window,
|
||||
user_data->dlg.draw_area_comments->style->fg_gc[GTK_WIDGET_STATE(widget)],
|
||||
user_data->dlg.pixmap_comments,
|
||||
0,0,
|
||||
|
@ -1520,6 +1596,9 @@ static void create_draw_area(graph_analysis_data_t* user_data, GtkWidget *box)
|
|||
|
||||
gtk_box_pack_start(GTK_BOX(box), hbox, TRUE, TRUE, 0);
|
||||
}
|
||||
/****************************************************************************/
|
||||
/* PUBLIC */
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -1645,6 +1724,9 @@ graph_analysis_data_t* graph_analysis_init(void)
|
|||
|
||||
return user_data;
|
||||
}
|
||||
/****************************************************************************/
|
||||
/* PUBLIC */
|
||||
/****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
void graph_analysis_create(graph_analysis_data_t* user_data)
|
||||
|
@ -1686,3 +1768,4 @@ void graph_analysis_update(graph_analysis_data_t* user_data)
|
|||
window_present(user_data->dlg.window);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue