"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/diagram.c" between
etherape-0.9.17.tar.gz and etherape-0.9.18.tar.gz

About: EtherApe is a GNOME/pcap-based graphical network monitor (etherman clone).

diagram.c  (etherape-0.9.17):diagram.c  (etherape-0.9.18)
skipping to change at line 23 skipping to change at line 23
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>. * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <libgnomecanvas/libgnomecanvas.h> #include <goocanvas.h>
#include "appdata.h" #include "appdata.h"
#include "diagram.h" #include "diagram.h"
#include "pref_dialog.h" #include "pref_dialog.h"
#include "stats/node.h" #include "stats/node.h"
#include "info_windows.h" #include "info_windows.h"
#include "stats/protocols.h" #include "stats/protocols.h"
#include "datastructs.h" #include "datastructs.h"
#include "names/ip-cache.h" #include "names/ip-cache.h"
#include "menus.h" #include "menus.h"
skipping to change at line 47 skipping to change at line 47
#include "export.h" #include "export.h"
#include "stats/util.h" #include "stats/util.h"
/* maximum node and link size */ /* maximum node and link size */
#define MAX_NODE_SIZE 5000 #define MAX_NODE_SIZE 5000
#define MAX_LINK_SIZE (MAX_NODE_SIZE/4) #define MAX_LINK_SIZE (MAX_NODE_SIZE/4)
gboolean already_updating; gboolean already_updating;
gboolean stop_requested; gboolean stop_requested;
static GnomeCanvasItem *pcap_stats_text_item = NULL;
static GnomeCanvasGroup *pcap_stats_text_group = NULL;
/*************************************************************************** /***************************************************************************
* *
* canvas_node_t definition and methods * canvas_node_t definition and methods
* *
**************************************************************************/ **************************************************************************/
typedef struct typedef struct
{ {
node_id_t canvas_node_id; node_id_t canvas_node_id;
GnomeCanvasItem *node_item; GooCanvasItem *node_item;
GnomeCanvasItem *text_item; GooCanvasItem *text_item;
GnomeCanvasGroup *group_item; GooCanvasGroup *group_item;
GdkColor color; GdkRGBA color;
gboolean is_new; gboolean is_new;
gboolean shown; /* True if it is to be displayed. */ gboolean shown; /* True if it is to be displayed. */
gboolean centered; /* true if is a center node */ gboolean centered; /* true if is a center node */
/* For '-P' mode (columnar layout) */ /* For '-P' mode (columnar layout) */
guint column; /* Which column this goes in */ guint column; /* Which column this goes in */
guint column_idx; /* Which position within its column this node is */ guint column_idx; /* Which position within its column this node is */
} }
canvas_node_t; canvas_node_t;
static gint canvas_node_compare(const node_id_t *a, const node_id_t *b, static gint canvas_node_compare(const node_id_t *a, const node_id_t *b,
gpointer dummy); gpointer dummy);
static void canvas_node_delete(canvas_node_t *cn); static void canvas_node_delete(canvas_node_t *cn);
static gint canvas_node_update(node_id_t * ether_addr, static gint canvas_node_update(node_id_t * ether_addr,
canvas_node_t * canvas_node, canvas_node_t * canvas_node,
GList ** delete_list); GList ** delete_list);
/*************************************************************************** /***************************************************************************
* *
* canvas_link_t definition and methods * canvas_link_t definition and methods
* *
**************************************************************************/ **************************************************************************/
typedef struct typedef struct
{ {
link_id_t canvas_link_id; /* id of the link */ link_id_t canvas_link_id; /* id of the link */
GnomeCanvasItem *src_item; /* triangle for src side */ GooCanvasItem *src_item; /* triangle for src side */
GnomeCanvasItem *dst_item; /* triangle for dst side */ GooCanvasItem *dst_item; /* triangle for dst side */
GdkColor color; GdkRGBA color;
} }
canvas_link_t; canvas_link_t;
static gint canvas_link_compare(const link_id_t *a, const link_id_t *b, static gint canvas_link_compare(const link_id_t *a, const link_id_t *b,
gpointer dummy); gpointer dummy);
static void canvas_link_delete(canvas_link_t *canvas_link); static void canvas_link_delete(canvas_link_t *canvas_link);
static gint canvas_link_update(link_id_t * link_id, static gint canvas_link_update(link_id_t * link_id,
canvas_link_t * canvas_link, canvas_link_t * canvas_link,
GList ** delete_list); GList ** delete_list);
struct node_ring struct node_ring
{ {
gfloat angle; gfloat angle;
guint node_i; guint node_i;
guint n_nodes; guint n_nodes;
}; };
typedef struct typedef struct
{ {
GtkWidget * canvas; GooCanvas * canvas;
struct node_ring outer; struct node_ring outer;
struct node_ring center; struct node_ring center;
gdouble xmin; gdouble xmin;
gdouble ymin; gdouble ymin;
gdouble xmax; gdouble xmax;
gdouble ymax; gdouble ymax;
gdouble x_rad_max; gdouble x_rad_max;
gdouble y_rad_max; gdouble y_rad_max;
skipping to change at line 132 skipping to change at line 130
} reposition_node_t; } reposition_node_t;
/*************************************************************************** /***************************************************************************
* *
* canvas_background_t definition and methods * canvas_background_t definition and methods
* *
**************************************************************************/ **************************************************************************/
typedef struct typedef struct
{ {
GnomeCanvasGroup *group;
gboolean use_image; gboolean use_image;
GdkColor color;
struct struct
{ {
GdkPixbuf *image; GdkPixbuf *image;
gchar *path; gchar *path;
GnomeCanvasItem *item; GooCanvasItem *item;
} image; } image;
} canvas_background_t; } canvas_background_t;
static void init_canvas_background(GtkWidget *canvas); static void init_canvas_background(GooCanvasItem *rootitem);
/*************************************************************************** /***************************************************************************
* *
* local variables * local variables
* *
**************************************************************************/ **************************************************************************/
static GTree *canvas_nodes; /* We don't use the nodes tree directly in order to static GTree *canvas_nodes = NULL; /* We don't use the nodes tree directly i n order to
* separate data from presentation: that is, we n eed to * separate data from presentation: that is, we n eed to
* keep a list of CanvasItems, but we do not want to keep * keep a list of CanvasItems, but we do not want to keep
* that info on the nodes tree itself */ * that info on the nodes tree itself */
static GTree *canvas_links; /* See canvas_nodes */ static GTree *canvas_links; /* See canvas_nodes */
static guint known_protocols = 0; static guint known_protocols = 0;
static canvas_background_t canvas_background; static canvas_background_t canvas_background;
static gboolean is_idle = FALSE;
static guint displayed_nodes; static guint displayed_nodes;
static gboolean need_reposition = TRUE; /* Force a diagram relayout */ static gboolean need_reposition = TRUE; /* Force a diagram relayout */
static gboolean need_font_refresh = TRUE;/* Force font refresh during layout */ static gboolean need_font_refresh = TRUE;/* Force font refresh during layout */
static gint diagram_timeout; /* Descriptor of the diagram timeout function static gint diagram_timeout = 0; /* Descriptor of the diagram timeout func
* (Used to change the refresh_period in the call tion
back */ * (Used to change the refresh_period in t
he callback */
static long canvas_obj_count = 0; /* counter of canvas objects */ static long canvas_obj_count = 0; /* counter of canvas objects */
static GnomeCanvas *gcanvas_ = NULL; /* drawing canvas */ static GooCanvas *gcanvas_ = NULL; /* drawing canvas */
static GooCanvasText *pcap_stats_text_item = NULL;
/*************************************************************************** /***************************************************************************
* *
* local Function definitions * local Function definitions
* *
**************************************************************************/ **************************************************************************/
static void diagram_update_nodes(GtkWidget * canvas); /* updates ALL nodes */ static gboolean update_diagram(GooCanvas *canvas); /* full diagram update */
static void diagram_update_links(GtkWidget * canvas); /* updates ALL links */ static void diagram_update_nodes(GooCanvas *canvas); /* updates ALL nodes */
static void diagram_update_background_image(GtkWidget *canvas); /* updates backg static void diagram_update_links(GooCanvas *canvas); /* updates ALL links */
round image */ static void diagram_update_background_image(GooCanvas *canvas); /* updates backg
round image */
static void check_new_protocol (GtkWidget *prot_table, const protostack_t *pstk) static void diagram_reposition(); /* reposition nodes */
;
static gint check_new_node (node_t * node, GtkWidget * canvas); static void check_new_protocol(GtkWidget *prot_table, const protostack_t *pstk);
static gboolean display_node (node_t * node); static gint check_new_node(node_t *node, GooCanvas *canvas);
static void limit_nodes (void); static gboolean display_node(node_t *node);
static gint add_ordered_node (node_id_t * node_id, static void limit_nodes(void);
canvas_node_t * canvas_node, static gint add_ordered_node(node_id_t *node_id,
GTree * ordered_nodes); canvas_node_t *canvas_node,
static gint check_ordered_node (gdouble * traffic, canvas_node_t * node, GTree *ordered_nodes);
guint * count); static gint check_ordered_node(gdouble *traffic, canvas_node_t *node,
static gint traffic_compare (gconstpointer a, gconstpointer b); guint *count);
static gint reposition_canvas_nodes (node_id_t * node_id, static gint traffic_compare(gconstpointer a, gconstpointer b);
canvas_node_t * canvas_node, static gint reposition_canvas_nodes(node_id_t *node_id,
reposition_node_t *data); canvas_node_t *canvas_node,
static gint reposition_canvas_nodes_prep(const node_id_t * node_id, reposition_node_t *data);
canvas_node_t * canvas_node, static gint reposition_canvas_nodes_prep(const node_id_t *node_id,
canvas_node_t *canvas_node,
reposition_node_t *data); reposition_node_t *data);
static gint check_new_link (link_id_t * link_id, static gint check_new_link(link_id_t *link_id,
link_t * link, GtkWidget * canvas); link_t *link,
static gdouble get_node_size (gdouble average); GooCanvas *canvas);
static gdouble get_node_size(gdouble average);
static gdouble get_link_size(const basic_stats_t *link_stats); static gdouble get_link_size(const basic_stats_t *link_stats);
static gint link_item_event (GnomeCanvasItem * item, static gint pcap_stats_text_item_event(GooCanvasItem *item, GdkEvent *event,
GdkEvent * event, canvas_link_t * canvas_link);
static gint node_item_event (GnomeCanvasItem * item,
GdkEvent * event, canvas_node_t * canvas_node);
static gint pcap_stats_text_item_event(GnomeCanvasItem *item, GdkEvent *event,
void *unused); void *unused);
static gboolean link_item_event(GooCanvasItem *item,
GooCanvasItem *target_item,
GdkEventButton *event,
canvas_link_t *canvas_link);
static gboolean node_item_event(GooCanvasItem *item,
GooCanvasItem *target_item,
GdkEventButton *event,
canvas_node_t *canvas_node);
static void update_legend(void); static void update_legend(void);
static void draw_oneside_link(double xs, double ys, double xd, double yd, static void draw_oneside_link(double xs, double ys, double xd, double yd,
const basic_stats_t *link_data, const basic_stats_t *link_data,
guint32 scaledColor, GnomeCanvasItem *item); const GdkRGBA *scaledColor, GooCanvasItem *item);
static void init_reposition(reposition_node_t *data, static void init_reposition(reposition_node_t *data,
GtkWidget * canvas, GooCanvas *canvas,
guint total_nodes); guint total_nodes);
static void clear_reposition(reposition_node_t *rdata); static void clear_reposition(reposition_node_t *rdata);
static void redraw_canvas_background(GooCanvas *canvas);
static gboolean diagram_resize_event(GtkWidget *widget,
const GdkEventConfigure *event,
GooCanvas *canvas);
/***************************************************************************
*
* implementation
*
**************************************************************************/
GtkWidget *canvas_widget() GtkWidget *canvas_widget()
{ {
return GTK_WIDGET(gcanvas_); return GTK_WIDGET(gcanvas_);
} }
static void goo_canvas_item_show(GooCanvasItem *it)
{
g_object_set(G_OBJECT (it),
"visibility", GOO_CANVAS_ITEM_VISIBLE,
NULL);
}
static void goo_canvas_item_hide(GooCanvasItem *it)
{
g_object_set(G_OBJECT (it),
"visibility", GOO_CANVAS_ITEM_INVISIBLE,
NULL);
}
void ask_reposition(gboolean r_font) void ask_reposition(gboolean r_font)
{ {
need_reposition = TRUE; need_reposition = TRUE;
need_font_refresh = r_font; need_font_refresh = r_font;
} }
void dump_stats(guint32 diff_msecs) void dump_stats(guint32 diff_msecs)
{ {
gchar *status_string; gchar *status_string;
long ipc=ipcache_active_entries(); long ipc=ipcache_active_entries();
skipping to change at line 267 skipping to change at line 293
if (INFO_ENABLED) if (INFO_ENABLED)
{ {
/* to check for resource leaks, we ask for a notify ... */ /* to check for resource leaks, we ask for a notify ... */
g_object_weak_ref(obj, finalize_callback, NULL); g_object_weak_ref(obj, finalize_callback, NULL);
++canvas_obj_count; ++canvas_obj_count;
} }
} }
/* It updates controls from values of variables, and connects control /* It updates controls from values of variables, and connects control
* signals to callback functions */ * signals to callback functions */
void init_diagram (GladeXML *xml) void init_diagram(GtkBuilder *xml)
{ {
GtkWidget *viewport;
GtkStyle *style;
GtkContainer *area; GtkContainer *area;
GooCanvasItem *rootitem;
GooCanvasItem *item;
GtkAllocation windowsize;
gulong sig_id;
// GtkWidget *viewport;
// GtkStyleContext *style;
// static GdkRGBA black = {0,0,0,0};
g_assert(gcanvas_ == NULL);
/* get containing window and size */
area = GTK_CONTAINER(gtk_builder_get_object(xml, "diagramwindow"));
g_assert(area != NULL);
gtk_widget_get_allocation(GTK_WIDGET(area), &windowsize);
/* Creates trees */ /* Creates trees */
canvas_nodes = g_tree_new_full ( (GCompareDataFunc)canvas_node_compare, canvas_nodes = g_tree_new_full( (GCompareDataFunc)canvas_node_compare,
NULL, NULL, (GDestroyNotify)canvas_node_delete); NULL, NULL, (GDestroyNotify)canvas_node_delete);
canvas_links = g_tree_new_full( (GCompareDataFunc)canvas_link_compare, canvas_links = g_tree_new_full( (GCompareDataFunc)canvas_link_compare,
NULL, NULL, (GDestroyNotify)canvas_link_delete); NULL, NULL, (GDestroyNotify)canvas_link_delete);
initialize_pref_controls(); initialize_pref_controls();
/* canvas */ /* canvas */
gcanvas_ = GNOME_CANVAS(gnome_canvas_new_aa()); gcanvas_ = GOO_CANVAS(goo_canvas_new());
g_assert(gcanvas_ != NULL); g_assert(gcanvas_ != NULL);
g_object_set(G_OBJECT(gcanvas_), g_object_set (G_OBJECT(gcanvas_),
"visible", TRUE, "background-color", "black",
"can_focus", TRUE,
// "width", 560,
// "height", 400,
"visibility", GNOME_CANVAS_ITEM_VISIBLE,
NULL); NULL);
g_signal_connect(G_OBJECT(gcanvas_), "size_allocate",
(GtkSignalFunc)on_canvas1_size_allocate, NULL); goo_canvas_set_bounds(gcanvas_,
-windowsize.width/2, -windowsize.height/2,
windowsize.width/2, windowsize.height/2);
gtk_widget_show(GTK_WIDGET(gcanvas_)); gtk_widget_show(GTK_WIDGET(gcanvas_));
area = GTK_CONTAINER(glade_xml_get_widget (xml, "diagramwindow"));
gtk_container_add(area, GTK_WIDGET(gcanvas_)); gtk_container_add(area, GTK_WIDGET(gcanvas_));
gnome_canvas_set_scroll_region(gcanvas_, -280, -200, 280, 200);
gnome_canvas_set_pixels_per_unit(gcanvas_, 1);
// rootitem = gnome_canvas_get_root_item(gcanvas_); rootitem = goo_canvas_get_root_item(gcanvas_);
/* Initialize background image */ /* Initialize background image */
init_canvas_background(GTK_WIDGET(gcanvas_)); g_object_set(G_OBJECT(gcanvas_), "background-color", "black", NULL);
init_canvas_background(rootitem);
/* Make legend background color match main display background color */ /* TODO: gtk3 handles background color via CSS...
// Make legend background color match main display background color
style = gtk_style_new(); style = gtk_style_new();
style->bg[GTK_STATE_NORMAL] = canvas_background.color; style->bg[GTK_STATE_NORMAL] = canvas_background.color;
style->base[GTK_STATE_NORMAL] = canvas_background.color; style->base[GTK_STATE_NORMAL] = canvas_background.color;
/* Set protocol legend background to black */ // Set protocol legend background to black
viewport = glade_xml_get_widget (appdata.xml, "legend_viewport"); viewport = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "legend_viewport"));
gtk_widget_set_style(viewport, style); gtk_widget_set_style(viewport, style);
gtk_style_set_background(style, gtk_widget_get_window(viewport), GTK_STATE_NOR MAL); gtk_style_set_background(style, gtk_widget_get_window(viewport), GTK_STATE_NOR MAL);
/* Create pcap stats text */ // should be gtk3 compatible, but doesn't work ...
pcap_stats_text_group = gnome_canvas_root(GNOME_CANVAS(gcanvas_)); viewport = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "legend_viewport"));
pcap_stats_text_group = GNOME_CANVAS_GROUP(gnome_canvas_item_new(pcap_stats_te gtk_widget_override_background_color(viewport,
xt_group, GTK_STATE_FLAG_NORMAL|GTK_STATE_FLAG_ACTIV
GNOME_TYPE_CA E,
NVAS_GROUP, &black);
"x", 0.0, */
"y", 0.0,
NULL)); item = goo_canvas_text_new(rootitem,
addref_canvas_obj(G_OBJECT(pcap_stats_text_group)); "",
0, 0, -1,
pcap_stats_text_item = gnome_canvas_item_new(pcap_stats_text_group, GOO_CANVAS_ANCHOR_NORTH_WEST,
GNOME_TYPE_CANVAS_TEXT, NULL); NULL);
pcap_stats_text_item = GOO_CANVAS_TEXT(item);
addref_canvas_obj(G_OBJECT(pcap_stats_text_item)); addref_canvas_obj(G_OBJECT(pcap_stats_text_item));
g_signal_connect(G_OBJECT(pcap_stats_text_item), "event", sig_id = g_signal_connect(G_OBJECT(area), "size-allocate",
(GtkSignalFunc)pcap_stats_text_item_event, NULL); G_CALLBACK(diagram_resize_event), gcanvas_);
g_assert(sig_id > 0);
sig_id = g_signal_connect(G_OBJECT(pcap_stats_text_item), "enter-notify-event"
,
G_CALLBACK(pcap_stats_text_item_event), NULL);
g_assert(sig_id > 0);
sig_id = g_signal_connect(G_OBJECT(pcap_stats_text_item), "leave-notify-event"
,
G_CALLBACK(pcap_stats_text_item_event), NULL);
g_assert(sig_id > 0);
/* Initialize the known_protocols table */ /* Initialize the known_protocols table */
delete_gui_protocols (); delete_gui_protocols ();
/* Set the already_updating global flag */ /* Set the already_updating global flag */
already_updating = FALSE; already_updating = FALSE;
stop_requested = FALSE; stop_requested = FALSE;
} /* init_diagram */ } /* init_diagram */
/* /*
* Initialize the canvas_background structure. * Initialize the canvas_background structure.
* Create a new group and add it to the root group. * Create a new group and add it to the root group.
* Create a new GnomeCanvasPixbufItem and add it to the new group. * Create a new GooCanvasPixbufItem and add it to the new group.
*/ */
static void init_canvas_background(GtkWidget *canvas) static void init_canvas_background(GooCanvasItem *rootitem)
{ {
GnomeCanvasGroup *group; canvas_background.image.item =
GtkAllocation allocation; goo_canvas_image_new(rootitem,
GtkStyle *style; NULL,
0, 0,
group = gnome_canvas_root(GNOME_CANVAS(canvas)); NULL);
canvas_background.group = GNOME_CANVAS_GROUP(gnome_canvas_item_new(group,
GNOME_TYPE_
CANVAS_GROUP,
"x", 0.0, "
y", 0.0,
NULL));
addref_canvas_obj(G_OBJECT(group));
canvas_background.image.item = gnome_canvas_item_new(canvas_background.group,
gnome_canvas_pixbuf_get_t
ype(),
"anchor", GTK_ANCHOR_NW,
NULL);
addref_canvas_obj(G_OBJECT(canvas_background.image.item)); addref_canvas_obj(G_OBJECT(canvas_background.image.item));
canvas_background.use_image = pref.bck_image_enabled; canvas_background.use_image = pref.bck_image_enabled;
canvas_background.image.path = g_strdup(pref.bck_image_path); canvas_background.image.path = g_strdup(pref.bck_image_path);
gdk_color_parse("black", &canvas_background.color);
gdk_colormap_alloc_color(gdk_colormap_get_system(), &canvas_background.color,
TRUE, TRUE);
style = gtk_style_new();
style->bg[GTK_STATE_NORMAL] = canvas_background.color;
style->base[GTK_STATE_NORMAL] = canvas_background.color;
gtk_widget_set_style(canvas, style);
gtk_style_set_background(style, gtk_widget_get_window(canvas), GTK_STATE_NORMA
L);
/**
* Have to set the scrolling region to the real allocated size of the canvas
* If not the image won't scale well in the redraw_canvas_background
* function until the on_canvas1_size_allocate callback is called
*/
gtk_widget_get_allocation(canvas, &allocation);
gnome_canvas_set_scroll_region(GNOME_CANVAS(canvas),
-(allocation.width)/2, -(allocation.height)/2,
(allocation.width)/2, (allocation.height)/2);
} }
/* /*
* Called by on_canvas1_size_allocate. * Called by on_canvas1_size_allocate.
* Try to load image from path. * Try to load image from path.
* On success image is scaled to the canvas size and printed. * On success image is scaled to the canvas size and printed.
* On error a blank black image is made and printed. * On error a blank black image is made and printed.
*/ */
void redraw_canvas_background(GtkWidget *canvas) static void redraw_canvas_background(GooCanvas *canvas)
{ {
GError* error = NULL; GError* error = NULL;
GtkAllocation canvas_size; GtkAllocation canvas_size;
if (canvas_background.use_image) { if (canvas_background.use_image) {
/* Get canvas dimensions */ /* Get canvas dimensions */
gtk_widget_get_allocation(canvas, &canvas_size); gtk_widget_get_allocation(GTK_WIDGET(canvas), &canvas_size);
if (canvas_background.image.image) { if (canvas_background.image.image) {
g_object_unref(G_OBJECT(canvas_background.image.image)); g_object_unref(G_OBJECT(canvas_background.image.image));
canvas_background.image.image = NULL; canvas_background.image.image = NULL;
} }
if (canvas_background.image.path && strlen(canvas_background.image.path)) if (canvas_background.image.path && strlen(canvas_background.image.path))
canvas_background.image.image = gdk_pixbuf_new_from_file_at_scale(canvas_b ackground.image.path, canvas_background.image.image = gdk_pixbuf_new_from_file_at_scale(canvas_b ackground.image.path,
canvas_s ize.width, canvas_size.height, canvas_s ize.width, canvas_size.height,
FALSE, & error); FALSE, & error);
gnome_canvas_item_set(canvas_background.image.item, g_object_set(G_OBJECT(canvas_background.image.item),
"pixbuf", canvas_background.image.image, "pixbuf", canvas_background.image.image,
"x", (double)-canvas_size.width/2, "x", (double)-canvas_size.width/2,
"y", (double)-canvas_size.height/2, "y", (double)-canvas_size.height/2,
NULL); "visibility", GOO_CANVAS_ITEM_VISIBLE,
NULL);
gnome_canvas_item_show(canvas_background.image.item);
} else { } else {
gnome_canvas_item_hide(canvas_background.image.item); g_object_set(G_OBJECT(canvas_background.image.item),
"visibility", GOO_CANVAS_ITEM_HIDDEN,
NULL);
} }
} }
/* /*
* Update the background image. Load new image if user selected another path * Update the background image. Load new image if user selected another path
* in preferences. Place the background image behind the nodes and links. * in preferences. Place the background image behind the nodes and links.
*/ */
static void diagram_update_background_image(GtkWidget *canvas) static void diagram_update_background_image(GooCanvas *canvas)
{ {
/* /*
* If the background image enable toggle or the image path has changed, we * If the background image enable toggle or the image path has changed, we
* need to update the background. * need to update the background.
*/ */
if (pref.bck_image_enabled != canvas_background.use_image if (pref.bck_image_enabled != canvas_background.use_image
|| g_strcmp0(canvas_background.image.path, pref.bck_image_path)) { || g_strcmp0(canvas_background.image.path, pref.bck_image_path)) {
canvas_background.use_image = pref.bck_image_enabled; canvas_background.use_image = pref.bck_image_enabled;
g_free(canvas_background.image.path); g_free(canvas_background.image.path);
canvas_background.image.path = g_strdup(pref.bck_image_path); canvas_background.image.path = g_strdup(pref.bck_image_path);
redraw_canvas_background(canvas); redraw_canvas_background(canvas);
} }
/* Draw the background first */ /* Draw the background first */
gnome_canvas_item_lower_to_bottom(GNOME_CANVAS_ITEM(canvas_background.group)); if (canvas_background.image.item) {
gnome_canvas_item_request_update(canvas_background.image.item); goo_canvas_item_lower(GOO_CANVAS_ITEM(canvas_background.image.item), NULL);
goo_canvas_item_request_update(GOO_CANVAS_ITEM(canvas_background.image.item)
);
}
} }
void destroying_timeout(gpointer data) static gboolean diagram_resize_event(GtkWidget *widget,
{ const GdkEventConfigure *event,
diagram_timeout = g_idle_add_full(G_PRIORITY_DEFAULT, GooCanvas *canvas)
update_diagram, {
data, GtkAllocation windowsize;
destroying_idle); g_assert(widget != NULL);
is_idle = TRUE; g_assert(canvas == gcanvas_);
}
gtk_widget_get_allocation(GTK_WIDGET(widget), &windowsize);
goo_canvas_set_bounds(canvas,
-windowsize.width/2, -windowsize.height/2,
windowsize.width/2, windowsize.height/2);
void destroying_idle(gpointer data) redraw_canvas_background(canvas);
{ diagram_reposition(canvas);
diagram_timeout = g_timeout_add_full (G_PRIORITY_DEFAULT, return FALSE;
pref.refresh_period,
update_diagram,
data,
destroying_timeout);
is_idle = FALSE;
} }
/* delete the specified canvas node */ /* delete the specified canvas node */
static void static void canvas_node_delete(canvas_node_t *canvas_node)
canvas_node_delete(canvas_node_t *canvas_node)
{ {
if (canvas_node->node_item) if (canvas_node->node_item)
{ {
gtk_object_destroy (GTK_OBJECT (canvas_node->node_item)); goo_canvas_item_remove(canvas_node->node_item);
g_object_unref (G_OBJECT (canvas_node->node_item)); // gtk_object_destroy(GTK_OBJECT(canvas_node->node_item));
// g_object_unref(G_OBJECT (canvas_node->node_item));
canvas_node->node_item = NULL; canvas_node->node_item = NULL;
} }
if (canvas_node->text_item) if (canvas_node->text_item)
{ {
gtk_object_destroy (GTK_OBJECT (canvas_node->text_item)); goo_canvas_item_remove(canvas_node->text_item);
g_object_unref (G_OBJECT (canvas_node->text_item)); // gtk_object_destroy(GTK_OBJECT (canvas_node->text_item));
// g_object_unref(G_OBJECT (canvas_node->text_item));
canvas_node->text_item = NULL; canvas_node->text_item = NULL;
} }
if (canvas_node->group_item) if (canvas_node->group_item)
{ {
gtk_object_destroy (GTK_OBJECT (canvas_node->group_item)); goo_canvas_item_remove(GOO_CANVAS_ITEM(canvas_node->group_item));
g_object_unref (G_OBJECT (canvas_node->group_item)); // gtk_object_destroy(GTK_OBJECT (canvas_node->group_item));
// g_object_unref(G_OBJECT (canvas_node->group_item));
canvas_node->group_item = NULL; canvas_node->group_item = NULL;
} }
g_free (canvas_node); g_free (canvas_node);
} }
/* used to remove nodes */ /* used to remove nodes */
static void static void gfunc_remove_canvas_node(gpointer data, gpointer user_data)
gfunc_remove_canvas_node(gpointer data, gpointer user_data)
{ {
g_tree_remove (canvas_nodes, (const node_id_t *)data); g_tree_remove(canvas_nodes, (const node_id_t *)data);
} }
/* used to remove links */ /* used to remove links */
static void static void gfunc_remove_canvas_link(gpointer data, gpointer user_data)
gfunc_remove_canvas_link(gpointer data, gpointer user_data)
{ {
g_tree_remove (canvas_links, (const link_id_t *)data); g_tree_remove(canvas_links, (const link_id_t *)data);
} }
static void static void diagram_update_nodes(GooCanvas *canvas)
diagram_update_nodes(GtkWidget * canvas)
{ {
GList *delete_list = NULL; GList *delete_list = NULL;
node_t *new_node = NULL; node_t *new_node = NULL;
/* Deletes all nodes and updates traffic values */ /* Deletes all nodes and updates traffic values */
/* TODO To reduce CPU usage, I could just as well update each specific /* TODO To reduce CPU usage, I could just as well update each specific
* node in update_canvas_nodes and create a new timeout function that would * node in update_canvas_nodes and create a new timeout function that would
* make sure that old nodes get deleted by calling update_nodes, but * make sure that old nodes get deleted by calling update_nodes, but
* not as often as with diagram_refresh_period */ * not as often as with diagram_refresh_period */
nodes_catalog_update_all(); nodes_catalog_update_all();
/* Check if there are any new nodes */ /* Check if there are any new nodes */
while ((new_node = new_nodes_pop())) while ((new_node = new_nodes_pop()))
check_new_node (new_node, canvas); check_new_node(new_node, canvas);
/* Update nodes look and queue outdated canvas_nodes for deletion */ /* Update nodes look and queue outdated canvas_nodes for deletion */
g_tree_foreach(canvas_nodes, g_tree_foreach(canvas_nodes,
(GTraverseFunc) canvas_node_update, (GTraverseFunc) canvas_node_update,
&delete_list); &delete_list);
/* delete all canvas nodes queued */ /* delete all canvas nodes queued */
g_list_foreach(delete_list, gfunc_remove_canvas_node, NULL); g_list_foreach(delete_list, gfunc_remove_canvas_node, NULL);
/* free the list - list items are already destroyed */ /* free the list - list items are already destroyed */
g_list_free(delete_list); g_list_free(delete_list);
/* Limit the number of nodes displayed, if a limit has been set */ /* Limit the number of nodes displayed, if a limit has been set */
/* TODO check whether this is the right function to use, now that we have a mo re /* TODO check whether this is the right function to use, now that we have a mo re
* general display_node called in update_canvas_nodes */ * general display_node called in update_canvas_nodes */
limit_nodes (); limit_nodes ();
/* Reposition canvas_nodes */ /* Reposition canvas_nodes */
if (need_reposition) if (need_reposition)
{ diagram_reposition(canvas);
reposition_node_t rdata; }
init_reposition(&rdata, canvas, displayed_nodes);
g_tree_foreach(canvas_nodes, /* handle node repositioning */
(GTraverseFunc) reposition_canvas_nodes_prep, static void diagram_reposition(GooCanvas *canvas)
&rdata); {
reposition_node_t rdata;
init_reposition(&rdata, canvas, displayed_nodes);
rdata.center.node_i = rdata.center.n_nodes; g_tree_foreach(canvas_nodes,
rdata.outer.node_i = rdata.outer.n_nodes; (GTraverseFunc) reposition_canvas_nodes_prep,
&rdata);
g_tree_foreach(canvas_nodes, rdata.center.node_i = rdata.center.n_nodes;
(GTraverseFunc) reposition_canvas_nodes, rdata.outer.node_i = rdata.outer.n_nodes;
&rdata);
clear_reposition(&rdata); g_tree_foreach(canvas_nodes,
(GTraverseFunc) reposition_canvas_nodes,
&rdata);
need_reposition = FALSE; clear_reposition(&rdata);
need_font_refresh = FALSE;
} need_reposition = FALSE;
need_font_refresh = FALSE;
} }
static void static void diagram_update_links(GooCanvas *canvas)
diagram_update_links(GtkWidget * canvas)
{ {
GList *delete_list = NULL; GList *delete_list = NULL;
/* Delete old capture links and update capture link variables */ /* Delete old capture links and update capture link variables */
links_catalog_update_all(); links_catalog_update_all();
/* Check if there are any new links */ /* Check if there are any new links */
links_catalog_foreach((GTraverseFunc) check_new_link, canvas); links_catalog_foreach((GTraverseFunc) check_new_link, canvas);
/* Update links look /* Update links look
skipping to change at line 606 skipping to change at line 624
return g_strdup(_("(Capture statistics unavailable in offline mode.)")); return g_strdup(_("(Capture statistics unavailable in offline mode.)"));
get_capture_stats(&stats); get_capture_stats(&stats);
return g_strdup_printf("%-12s %12u\n%-12s %12u\n%-12s %12u", "recv:", return g_strdup_printf("%-12s %12u\n%-12s %12u\n%-12s %12u", "recv:",
stats.ps_recv, "drop:", stats.ps_drop, stats.ps_recv, "drop:", stats.ps_drop,
"ifdrop:", stats.ps_ifdrop); "ifdrop:", stats.ps_ifdrop);
} }
/* Update libpcap stats counters display */ /* Update libpcap stats counters display */
static void update_pcap_stats_text(GtkWidget *canvas) static void update_pcap_stats_text(GooCanvas *canvas)
{ {
gdouble xmin, xmax, ymin, ymax, xpos, ypos; gdouble xmin, xmax, ymin, ymax, xpos, ypos;
GtkAnchorType anchor; GooCanvasAnchorType anchor;
gchar *tmpstr; gchar *tmpstr;
if (pref.pcap_stats_pos == STATSPOS_NONE) if (pref.pcap_stats_pos == STATSPOS_NONE)
{ {
gnome_canvas_item_hide(pcap_stats_text_item); g_object_set(G_OBJECT(pcap_stats_text_item),
"visibility", GOO_CANVAS_ITEM_HIDDEN,
NULL);
return; return;
} }
else
gnome_canvas_item_show(pcap_stats_text_item);
if (get_capture_status() != PLAY) if (get_capture_status() != PLAY)
return; return;
gnome_canvas_get_scroll_region(GNOME_CANVAS(canvas), &xmin, &ymin, &xmax, &yma x); goo_canvas_get_bounds(canvas, &xmin, &ymin, &xmax, &ymax);
switch (pref.pcap_stats_pos) switch (pref.pcap_stats_pos)
{ {
case STATSPOS_UPPER_LEFT: case STATSPOS_UPPER_LEFT:
xpos = xmin; xpos = xmin;
ypos = ymin; ypos = ymin;
anchor = GTK_ANCHOR_NW; anchor = GOO_CANVAS_ANCHOR_NORTH_WEST;
break; break;
case STATSPOS_UPPER_RIGHT: case STATSPOS_UPPER_RIGHT:
xpos = xmax; xpos = xmax;
ypos = ymin; ypos = ymin;
anchor = GTK_ANCHOR_NE; anchor = GOO_CANVAS_ANCHOR_NORTH_EAST;
break; break;
case STATSPOS_LOWER_LEFT: case STATSPOS_LOWER_LEFT:
xpos = xmin; xpos = xmin;
ypos = ymax; ypos = ymax;
anchor = GTK_ANCHOR_SW; anchor = GOO_CANVAS_ANCHOR_SOUTH_WEST;
break; break;
case STATSPOS_LOWER_RIGHT: case STATSPOS_LOWER_RIGHT:
xpos = xmax; xpos = xmax;
ypos = ymax; ypos = ymax;
anchor = GTK_ANCHOR_SE; anchor = GOO_CANVAS_ANCHOR_SOUTH_EAST;
break; break;
default: default:
g_error(_("Bogus statspos_t (%d) pref.pcap_stats_pos"), pref.pcap_stats_po s); g_error(_("Bogus statspos_t (%d) pref.pcap_stats_pos"), pref.pcap_stats_po s);
return; return;
} }
tmpstr = get_pcap_stats_string(); tmpstr = get_pcap_stats_string();
gnome_canvas_item_set(pcap_stats_text_item, g_object_set(G_OBJECT(pcap_stats_text_item),
"text", tmpstr, "text", tmpstr,
"x", xpos, "y", ypos, "x", xpos, "y", ypos,
"font", pref.fontname, "font", pref.fontname,
"fill_color", pref.text_color, "fill_color", pref.text_color,
"anchor", anchor, "anchor", anchor,
"visibility", GOO_CANVAS_ITEM_VISIBLE,
NULL); NULL);
g_free(tmpstr); g_free(tmpstr);
} }
/* Refreshes the diagram. Called each refresh_period ms /* Refreshes the diagram. Called each refresh_period ms
* 1. Checks for new protocols and displays them * 1. Checks for new protocols and displays them
* 2. Updates nodes looks * 2. Updates nodes looks
* 3. Updates links looks * 3. Updates links looks
*/ */
gboolean update_diagram(gpointer data) static gboolean update_diagram(GooCanvas *canvas)
{ {
static struct timeval last_refresh_time = { 0, 0 }; static struct timeval last_refresh_time = { 0, 0 };
GtkWidget *canvas = (GtkWidget *)data;
double diffms;
capstatus_t status; capstatus_t status;
/* if requested and enabled, dump to xml */ /* if requested and enabled, dump to xml */
if (appdata.request_dump && appdata.export_file_signal) if (appdata.request_dump && appdata.export_file_signal)
{ {
g_warning (_("SIGUSR1 received: exporting to %s"), appdata.export_file_sig nal); g_warning (_("SIGUSR1 received: exporting to %s"), appdata.export_file_sig nal);
dump_xml(appdata.export_file_signal); dump_xml(appdata.export_file_signal);
appdata.request_dump = FALSE; appdata.request_dump = FALSE;
} }
skipping to change at line 745 skipping to change at line 762
* CPU with redraws */ * CPU with redraws */
if ((last_refresh_time.tv_sec == 0) && (last_refresh_time.tv_usec == 0)) if ((last_refresh_time.tv_sec == 0) && (last_refresh_time.tv_usec == 0))
last_refresh_time = appdata.gui_now; last_refresh_time = appdata.gui_now;
/* Force redraw */ /* Force redraw */
while (gtk_events_pending ()) while (gtk_events_pending ())
gtk_main_iteration (); gtk_main_iteration ();
gettimeofday(&appdata.gui_now, NULL); gettimeofday(&appdata.gui_now, NULL);
diffms = subtract_times_ms(&appdata.gui_now, &last_refresh_time);
last_refresh_time = appdata.gui_now; last_refresh_time = appdata.gui_now;
already_updating = FALSE; already_updating = FALSE;
if (!is_idle)
{
if (diffms > pref.refresh_period * 1.2)
return FALSE; /* Removes the timeout */
}
else
{
if (diffms < pref.refresh_period)
return FALSE; /* removes the idle */
}
if (stop_requested) if (stop_requested)
gui_stop_capture(); gui_stop_capture();
return TRUE; /* Keep on calling this function */ return TRUE; /* Keep on calling this function */
} /* update_diagram */ } /* update_diagram */
static void static void purge_expired_legend_protocol(GtkWidget *widget, gpointer data)
purge_expired_legend_protocol(GtkWidget *widget, gpointer data)
{ {
GtkLabel *lab = GTK_LABEL(widget); GtkLabel *lab = GTK_LABEL(widget);
if (lab && if (lab &&
!protocol_summary_find(pref.stack_level, gtk_label_get_label(lab))) !protocol_summary_find(pref.stack_level, gtk_label_get_label(lab)))
{ {
/* protocol expired, remove */ /* protocol expired, remove */
gtk_widget_destroy(widget); gtk_widget_destroy(widget);
known_protocols--; known_protocols--;
} }
} }
/* updates the legend */ /* updates the legend */
static void static void update_legend()
update_legend()
{ {
GtkWidget *prot_table; GtkWidget *prot_table;
/* first, check if there are expired protocols */ /* first, check if there are expired protocols */
prot_table = glade_xml_get_widget (appdata.xml, "prot_table"); prot_table = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "prot_table"));
if (!prot_table) if (!prot_table)
return; return;
gtk_container_foreach(GTK_CONTAINER(prot_table), gtk_container_foreach(GTK_CONTAINER(prot_table),
(GtkCallback)purge_expired_legend_protocol, NULL); (GtkCallback)purge_expired_legend_protocol, NULL);
/* then search for new protocols */ /* then search for new protocols */
check_new_protocol(prot_table, protocol_summary_stack()); check_new_protocol(prot_table, protocol_summary_stack());
} }
/* Checks whether there is already a legend entry for each known /* Checks whether there is already a legend entry for each known
* protocol. If not, create it */ * protocol. If not, create it */
static void static void check_new_protocol (GtkWidget *prot_table, const protostack_t *pstk)
check_new_protocol (GtkWidget *prot_table, const protostack_t *pstk)
{ {
const GList *protocol_item; const GList *protocol_item;
const protocol_t *protocol; const protocol_t *protocol;
GdkColor color; const GdkRGBA *color;
GtkStyle *style; // GtkStyle *style;
GtkLabel *lab; GtkLabel *lab;
GtkWidget *newlab; GtkWidget *newlab;
GList *childlist; GList *childlist;
gchar *mkupbuf = NULL;
if (!pstk) if (!pstk)
return; /* nothing to do */ return; /* nothing to do */
childlist = gtk_container_get_children(GTK_CONTAINER(prot_table)); childlist = gtk_container_get_children(GTK_CONTAINER(prot_table));
protocol_item = pstk->protostack[pref.stack_level]; protocol_item = pstk->protostack[pref.stack_level];
while (protocol_item) while (protocol_item)
{ {
const GList *cur; const GList *cur;
protocol = protocol_item->data; protocol = protocol_item->data;
skipping to change at line 844 skipping to change at line 847
if (cur) if (cur)
continue; /* found, skip to next */ continue; /* found, skip to next */
g_my_debug ("Protocol '%s' not found. Creating legend item", g_my_debug ("Protocol '%s' not found. Creating legend item",
protocol->name); protocol->name);
/* It's not, so we build a new entry on the legend */ /* It's not, so we build a new entry on the legend */
/* we add the new label widgets */ /* we add the new label widgets */
newlab = gtk_label_new (protocol->name); newlab = gtk_label_new(NULL);
gtk_widget_show (newlab); gtk_widget_show (newlab);
gtk_misc_set_alignment(GTK_MISC(newlab), 0, 0); // gtk_misc_set_alignment(GTK_MISC(newlab), 0, 0);
color = protohash_color(protocol->name); color = protohash_color(protocol->name);
if (!gdk_colormap_alloc_color mkupbuf = g_markup_printf_escaped(
"<span foreground=\"#%02x%02x%02x\">%s</span>",
(unsigned int)(color->red * 255),
(unsigned int)(color->green * 255),
(unsigned int)(color->blue * 255),
protocol->name);
gtk_label_set_markup(GTK_LABEL(newlab), mkupbuf);
g_free(mkupbuf);
/* if (!gdk_colormap_alloc_color
(gdk_colormap_get_system(), &color, FALSE, TRUE)) (gdk_colormap_get_system(), &color, FALSE, TRUE))
g_warning (_("Unable to allocate color for new protocol %s"), g_warning (_("Unable to allocate color for new protocol %s"),
protocol->name); protocol->name);
style = gtk_style_new (); style = gtk_style_new ();
style->fg[GTK_STATE_NORMAL] = color; style->fg[GTK_STATE_NORMAL] = color;
gtk_widget_set_style (newlab, style); gtk_widget_set_style (newlab, style);
g_object_unref (style); g_object_unref (style);
*/
gtk_container_add(GTK_CONTAINER(prot_table), newlab); gtk_container_add(GTK_CONTAINER(prot_table), newlab);
known_protocols++; known_protocols++;
} }
g_list_free(childlist); g_list_free(childlist);
} /* check_new_protocol */ } /* check_new_protocol */
/* empties the table of protocols */ /* empties the table of protocols */
void void delete_gui_protocols(void)
delete_gui_protocols (void)
{ {
GList *item; GList *item;
GtkContainer *prot_table; GtkContainer *prot_table;
known_protocols = 0; known_protocols = 0;
/* restart color cycle */ /* restart color cycle */
protohash_reset_cycle(); protohash_reset_cycle();
/* remove proto labels from legend */ /* remove proto labels from legend */
prot_table = GTK_CONTAINER (glade_xml_get_widget (appdata.xml, "prot_table")); prot_table = GTK_CONTAINER(gtk_builder_get_object(appdata.xml, "prot_table"));
item = gtk_container_get_children (GTK_CONTAINER (prot_table)); item = gtk_container_get_children (GTK_CONTAINER (prot_table));
while (item) while (item)
{ {
gtk_container_remove (prot_table, item->data); gtk_container_remove (prot_table, item->data);
item = item->next; item = item->next;
} }
/* resize legend */
gtk_container_resize_children(prot_table);
gtk_widget_queue_resize (GTK_WIDGET (appdata.app1)); gtk_widget_queue_resize (GTK_WIDGET (appdata.app1));
} /* delete_gui_protocols */ } /* delete_gui_protocols */
/* Checks if there is a canvas_node per each node. If not, one canvas_node /* Checks if there is a canvas_node per each node. If not, one canvas_node
* must be created and initiated */ * must be created and initiated */
static gint static gint check_new_node(node_t * node, GooCanvas *canvas)
check_new_node (node_t * node, GtkWidget * canvas)
{ {
canvas_node_t *new_canvas_node; canvas_node_t *new_canvas_node;
GnomeCanvasGroup *group; gulong sig_id;
if (!node) if (!node)
return FALSE; return FALSE;
if (display_node (node) && !g_tree_lookup (canvas_nodes, &node->node_id)) if (display_node(node) && !g_tree_lookup(canvas_nodes, &node->node_id))
{ {
GooCanvasItem *rootgroup;
GooCanvasItem *newgroup;
new_canvas_node = g_malloc (sizeof (canvas_node_t)); new_canvas_node = g_malloc (sizeof (canvas_node_t));
g_assert(new_canvas_node); g_assert(new_canvas_node);
new_canvas_node->canvas_node_id = node->node_id; new_canvas_node->canvas_node_id = node->node_id;
/* Create a new group to hold the node and its labels */ /* Create a new group to hold the node and its labels */
group = gnome_canvas_root (GNOME_CANVAS (canvas)); rootgroup = goo_canvas_get_root_item(canvas);
g_assert(group); newgroup = goo_canvas_group_new(rootgroup,
group = GNOME_CANVAS_GROUP (gnome_canvas_item_new (group, "x", 100.0,
GNOME_TYPE_CANVAS_GROUP, "y", 100.0,
"x", 100.0, NULL);
"y", 100.0, NULL)); addref_canvas_obj(G_OBJECT(newgroup));
g_assert(group); new_canvas_node->group_item = GOO_CANVAS_GROUP(newgroup);
addref_canvas_obj(G_OBJECT (group));
new_canvas_node->group_item = group; /* create circle and text, initially hidden until proper repositioned */
new_canvas_node->node_item = goo_canvas_ellipse_new(newgroup,
new_canvas_node->node_item 0.0,
= gnome_canvas_item_new (group, 0.0,
GNOME_TYPE_CANVAS_ELLIPSE, 0.0,
"x1", 0.0, 0.0,
"x2", 0.0, "fill-color", "white",
"y1", 0.0, "stroke-color", "black",
"y2", 0.0, "line-width", 0,
"fill_color", "white", "visibility", GOO_CANVAS_ITEM_INVISIBLE,
"outline_color", "black", NULL);
"width_pixels", 0, NULL); addref_canvas_obj(G_OBJECT(new_canvas_node->node_item));
addref_canvas_obj(G_OBJECT (new_canvas_node->node_item));
new_canvas_node->text_item =
gnome_canvas_item_new (group, GNOME_TYPE_CANVAS_TEXT,
"text", node->name->str,
"x", 0.0,
"y", 0.0,
"anchor", GTK_ANCHOR_CENTER,
"font", pref.fontname,
"fill_color", pref.text_color, NULL);
addref_canvas_obj(G_OBJECT (new_canvas_node->text_item));
gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM new_canvas_node->text_item = goo_canvas_text_new(newgroup,
(new_canvas_node->text_item)); node->name->str,
g_signal_connect (G_OBJECT (new_canvas_node->group_item), "event", 0.0,
G_CALLBACK(node_item_event), new_canvas_node); 0.0,
-1,
GOO_CANVAS_ANCHOR_CENTER,
"font", pref.fontname,
"fill-color", pref.text_color,
"visibility", GOO_CANVAS_ITEM_INVISIBLE,
NULL);
addref_canvas_obj(G_OBJECT(new_canvas_node->text_item));
goo_canvas_item_raise(new_canvas_node->text_item, NULL);
sig_id = g_signal_connect(G_OBJECT(new_canvas_node->text_item),
"button-release-event",
G_CALLBACK(node_item_event),
new_canvas_node);
g_assert(sig_id > 0);
sig_id = g_signal_connect(G_OBJECT(new_canvas_node->node_item),
"button-release-event",
G_CALLBACK(node_item_event),
new_canvas_node);
g_assert(sig_id > 0);
if (!new_canvas_node->node_item || !new_canvas_node->text_item) if (!new_canvas_node->node_item || !new_canvas_node->text_item)
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, _("Canvas node null")); g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, _("Canvas node null"));
/*
* We hide them until we are sure that they will get a proper position
* in reposition_nodes
*/
gnome_canvas_item_hide (new_canvas_node->node_item);
gnome_canvas_item_hide (new_canvas_node->text_item);
new_canvas_node->is_new = TRUE; new_canvas_node->is_new = TRUE;
new_canvas_node->shown = TRUE; new_canvas_node->shown = TRUE;
new_canvas_node->centered = FALSE; new_canvas_node->centered = FALSE;
g_tree_insert (canvas_nodes, g_tree_insert (canvas_nodes,
&new_canvas_node->canvas_node_id, new_canvas_node); &new_canvas_node->canvas_node_id, new_canvas_node);
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
_("Creating canvas_node: %s. Number of nodes %d"), _("Creating canvas_node: %s. Number of nodes %d"),
node->name->str, g_tree_nnodes (canvas_nodes)); node->name->str, g_tree_nnodes (canvas_nodes));
need_reposition = TRUE; need_reposition = TRUE;
} }
return FALSE; /* False to keep on traversing */ return FALSE; /* False to keep on traversing */
} /* check_new_node */ } /* check_new_node */
/* - updates sizes, names, etc */ /* - updates sizes, names, etc */
static gint static gint canvas_node_update(node_id_t *node_id, canvas_node_t *canvas_node,
canvas_node_update(node_id_t * node_id, canvas_node_t * canvas_node, GList **delete_list)
GList **delete_list)
{ {
node_t *node; node_t *node;
gdouble node_size; gdouble node_size;
static clock_t start = 0; static clock_t start = 0;
clock_t end; clock_t end;
gdouble cpu_time_used; gdouble cpu_time_used;
char *nametmp = NULL; char *nametmp = NULL;
node = nodes_catalog_find(node_id); node = nodes_catalog_find(node_id);
skipping to change at line 1000 skipping to change at line 1011
/* adds current to list of canvas nodes to delete */ /* adds current to list of canvas nodes to delete */
*delete_list = g_list_prepend( *delete_list, node_id); *delete_list = g_list_prepend( *delete_list, node_id);
g_my_debug ("Queueing canvas node to remove."); g_my_debug ("Queueing canvas node to remove.");
need_reposition = TRUE; need_reposition = TRUE;
return FALSE; return FALSE;
} }
switch (pref.node_size_variable) switch (pref.node_size_variable)
{ {
case INST_TOTAL: case INST_TOTAL:
node_size = get_node_size (node->node_stats.stats.average); node_size = get_node_size(node->node_stats.stats.average);
break; break;
case INST_INBOUND: case INST_INBOUND:
node_size = get_node_size (node->node_stats.stats_in.average); node_size = get_node_size(node->node_stats.stats_in.average);
break; break;
case INST_OUTBOUND: case INST_OUTBOUND:
node_size = get_node_size (node->node_stats.stats_out.average); node_size = get_node_size(node->node_stats.stats_out.average);
break; break;
case INST_PACKETS: case INST_PACKETS:
node_size = get_node_size (node->node_stats.pkt_list.length); node_size = get_node_size(node->node_stats.pkt_list.length);
break; break;
case ACCU_TOTAL: case ACCU_TOTAL:
node_size = get_node_size (node->node_stats.stats.accumulated); node_size = get_node_size(node->node_stats.stats.accumulated);
break; break;
case ACCU_INBOUND: case ACCU_INBOUND:
node_size = get_node_size (node->node_stats.stats_in.accumulated); node_size = get_node_size(node->node_stats.stats_in.accumulated);
break; break;
case ACCU_OUTBOUND: case ACCU_OUTBOUND:
node_size = get_node_size (node->node_stats.stats_out.accumulated); node_size = get_node_size(node->node_stats.stats_out.accumulated);
break; break;
case ACCU_PACKETS: case ACCU_PACKETS:
node_size = get_node_size (node->node_stats.stats.accu_packets); node_size = get_node_size(node->node_stats.stats.accu_packets);
break; break;
case ACCU_AVG_SIZE: case ACCU_AVG_SIZE:
node_size = get_node_size (node->node_stats.stats.avg_size); node_size = get_node_size(node->node_stats.stats.avg_size);
break; break;
default: default:
node_size = get_node_size (node->node_stats.stats_out.average); node_size = get_node_size(node->node_stats.stats_out.average);
g_warning (_("Unknown value or node_size_variable")); g_warning (_("Unknown value or node_size_variable"));
} }
/* limit the maximum size to avoid overload */ /* limit the maximum size to avoid overload */
if (node_size > MAX_NODE_SIZE) if (node_size > MAX_NODE_SIZE)
node_size = MAX_NODE_SIZE; node_size = MAX_NODE_SIZE;
if (node->main_prot[pref.stack_level]) if (node->main_prot[pref.stack_level])
{ {
canvas_node->color = protohash_color(node->main_prot[pref.stack_level]); canvas_node->color = *protohash_color(node->main_prot[pref.stack_level]);
gnome_canvas_item_set (canvas_node->node_item, g_object_set(G_OBJECT(canvas_node->node_item),
"x1", -node_size / 2, "radius-x", node_size / 2,
"x2", node_size / 2, "radius-y", node_size / 2,
"y1", -node_size / 2, "fill-color-gdk-rgba", &canvas_node->color,
"y2", node_size / 2, "visibility", GOO_CANVAS_ITEM_VISIBLE,
"fill_color_gdk", &(canvas_node->color), NULL); NULL);
goo_canvas_item_show(canvas_node->text_item);
} }
else else
{ {
guint32 black = 0x000000ff; guint32 black = 0x000000ff;
gnome_canvas_item_set (canvas_node->node_item, g_object_set(G_OBJECT(canvas_node->node_item),
"x1", -node_size / 2, "radius-x", node_size / 2,
"x2", node_size / 2, "radius-y", node_size / 2,
"y1", -node_size / 2, "fill_color_rgba", black,
"y2", node_size / 2, "visibility", GOO_CANVAS_ITEM_VISIBLE,
"fill_color_rgba", black, NULL); NULL);
} }
/* We check the name of the node, and update the canvas node name /* We check the name of the node, and update the canvas node name
* if it has changed (useful for non blocking dns resolving) */ * if it has changed (useful for non blocking dns resolving) */
/*TODO why is it exactly that sometimes it is NULL? */
if (canvas_node->text_item) if (canvas_node->text_item)
{ {
g_object_get (G_OBJECT (canvas_node->text_item), g_object_get(G_OBJECT(canvas_node->text_item),
"text", &nametmp, "text", &nametmp,
NULL); NULL);
if (strcmp (nametmp, node->name->str)) if (strcmp(nametmp, node->name->str))
{ {
gnome_canvas_item_set (canvas_node->text_item, g_object_set(G_OBJECT(canvas_node->text_item),
"text", node->name->str, "text", node->name->str,
NULL); NULL);
gnome_canvas_item_request_update (canvas_node->text_item); goo_canvas_item_request_update(canvas_node->text_item);
} }
g_free (nametmp); g_free (nametmp);
} }
/* Processor time check. If too much time has passed, update the GUI */ /* Processor time check. If too much time has passed, update the GUI */
end = clock (); end = clock ();
cpu_time_used = ((gdouble) (end - start)) / CLOCKS_PER_SEC; cpu_time_used = ((gdouble) (end - start)) / CLOCKS_PER_SEC;
if (cpu_time_used > 0.05) if (cpu_time_used > 0.05)
{ {
/* Force redraw */ /* Force redraw */
while (gtk_events_pending ()) while (gtk_events_pending ())
gtk_main_iteration (); gtk_main_iteration ();
start = end; start = end;
} }
return FALSE; /* False means keep on calling the functi on */ return FALSE; /* False means keep on calling the functi on */
} /* update_canvas_nodes */ } /* update_canvas_nodes */
/* Returns whether the node in question should be displayed in the /* Returns whether the node in question should be displayed in the
* diagram or not */ * diagram or not */
static gboolean static gboolean display_node(node_t *node)
display_node (node_t * node)
{ {
double diffms; double diffms;
if (!node) if (!node)
return FALSE; return FALSE;
diffms = subtract_times_ms(&appdata.now, &node->node_stats.stats.last_time); diffms = subtract_times_ms(&appdata.now, &node->node_stats.stats.last_time);
/* There are problems if a canvas_node is deleted if it still /* There are problems if a canvas_node is deleted if it still
* has packets, so we have to check that as well */ * has packets, so we have to check that as well */
skipping to change at line 1120 skipping to change at line 1130
#if 1 #if 1
if ((pref.gui_node_timeout_time == 1) && !node->node_stats.pkt_list.length) if ((pref.gui_node_timeout_time == 1) && !node->node_stats.pkt_list.length)
g_my_critical ("Impossible situation in display node"); g_my_critical ("Impossible situation in display node");
#endif #endif
return TRUE; return TRUE;
} /* display_node */ } /* display_node */
/* Sorts canvas nodes with the criterium set in preferences and sets /* Sorts canvas nodes with the criterium set in preferences and sets
* which will be displayed in the diagram */ * which will be displayed in the diagram */
static void static void limit_nodes(void)
limit_nodes (void)
{ {
static GTree *ordered_nodes = NULL; static GTree *ordered_nodes = NULL;
static guint limit; static guint limit;
displayed_nodes = 0; /* We'll increment for each node we don't displayed_nodes = 0; /* We'll increment for each node we don't
* limit */ * limit */
if (appdata.node_limit < 0) if (appdata.node_limit < 0)
{ {
displayed_nodes = g_tree_nnodes (canvas_nodes); displayed_nodes = g_tree_nnodes (canvas_nodes);
return; return;
skipping to change at line 1145 skipping to change at line 1154
ordered_nodes = g_tree_new (traffic_compare); ordered_nodes = g_tree_new (traffic_compare);
g_tree_foreach(canvas_nodes, (GTraverseFunc) add_ordered_node, ordered_nodes); g_tree_foreach(canvas_nodes, (GTraverseFunc) add_ordered_node, ordered_nodes);
g_tree_foreach(ordered_nodes, (GTraverseFunc) check_ordered_node, g_tree_foreach(ordered_nodes, (GTraverseFunc) check_ordered_node,
&limit); &limit);
g_tree_destroy (ordered_nodes); g_tree_destroy (ordered_nodes);
ordered_nodes = NULL; ordered_nodes = NULL;
} /* limit_nodes */ } /* limit_nodes */
static gint static gint add_ordered_node(node_id_t *node_id, canvas_node_t *node,
add_ordered_node (node_id_t * node_id, canvas_node_t * node, GTree * ordered_nodes)
GTree * ordered_nodes) {
{ g_tree_insert(ordered_nodes, node, node);
g_tree_insert (ordered_nodes, node, node); g_my_debug("Adding ordered node. Number of nodes: %d",
g_my_debug ("Adding ordered node. Number of nodes: %d", g_tree_nnodes(ordered_nodes));
g_tree_nnodes (ordered_nodes));
return FALSE; /* keep on traversing */ return FALSE; /* keep on traversing */
} /* add_ordered_node */ } /* add_ordered_node */
static gint static gint check_ordered_node(gdouble *traffic, canvas_node_t *node, guint *cou
check_ordered_node (gdouble * traffic, canvas_node_t * node, guint * count) nt)
{ {
/* TODO We can probably optimize this by stopping the traversion once /* TODO We can probably optimize this by stopping the traversion once
* the limit has been reached */ * the limit has been reached */
if (*count) if (*count) {
{ if (!node->shown)
if (!node->shown) need_reposition = TRUE;
need_reposition = TRUE; node->shown = TRUE;
node->shown = TRUE; ++displayed_nodes;
displayed_nodes++; (*count)--;
(*count)--; } else {
} if (node->shown)
else need_reposition = TRUE;
{ node->shown = FALSE;
if (node->shown) }
need_reposition = TRUE; return FALSE; /* keep on traversing */
node->shown = FALSE; }
}
return FALSE; /* keep on traversing */
} /* check_ordered_node */
/* Comparison function used to order the (GTree *) nodes /* Comparison function used to order the (GTree *) nodes
* and canvas_nodes heard on the network */ * and canvas_nodes heard on the network */
static gint static gint traffic_compare(gconstpointer a, gconstpointer b)
traffic_compare (gconstpointer a, gconstpointer b)
{ {
node_t *node_a, *node_b; node_t *node_a, *node_b;
g_assert (a != NULL); g_assert (a != NULL);
g_assert (b != NULL); g_assert (b != NULL);
node_a = (node_t *) a; node_a = (node_t *) a;
node_b = (node_t *) b; node_b = (node_t *) b;
if (node_a->node_stats.stats.average < node_b->node_stats.stats.average) if (node_a->node_stats.stats.average < node_b->node_stats.stats.average)
skipping to change at line 1204 skipping to change at line 1207
/* If two nodes have the same traffic, we still have /* If two nodes have the same traffic, we still have
* to distinguish them somehow. We use the node_id */ * to distinguish them somehow. We use the node_id */
return (node_id_compare (&node_a->node_id, &node_b->node_id)); return (node_id_compare (&node_a->node_id, &node_b->node_id));
} /* traffic_compare */ } /* traffic_compare */
/* initialize reposition struct */ /* initialize reposition struct */
static void init_reposition(reposition_node_t *data, static void init_reposition(reposition_node_t *data,
GtkWidget * canvas, GooCanvas *canvas,
guint total_nodes) guint total_nodes)
{ {
gdouble text_compensation = 50; gdouble text_compensation = 50;
data->canvas = canvas; data->canvas = canvas;
memset(&data->center, 0, sizeof(data->center)); memset(&data->center, 0, sizeof(data->center));
memset(&data->outer, 0, sizeof(data->outer)); memset(&data->outer, 0, sizeof(data->outer));
/* /*
* Offset the starting angle on the center ring so that when there are * Offset the starting angle on the center ring so that when there are
* relatively few nodes displayed (e.g. 4 central and 4 outer) the links * relatively few nodes displayed (e.g. 4 central and 4 outer) the links
* obscure things less (by not overlapping node labels and other links). * obscure things less (by not overlapping node labels and other links).
*/ */
data->center.angle += M_PI / 4.0; data->center.angle += M_PI / 4.0;
if (appdata.column_patterns) if (appdata.column_patterns)
data->column_populations = g_malloc0(appdata.column_patterns->len + 1 * data->column_populations = g_malloc0(appdata.column_patterns->len + 1 *
sizeof(*data->column_populations)); sizeof(*data->column_populations));
gnome_canvas_get_scroll_region(GNOME_CANVAS (canvas), goo_canvas_get_bounds(canvas,
&data->xmin, &data->ymin, &data->xmin, &data->ymin,
&data->xmax, &data->ymax); &data->xmax, &data->ymax);
data->xmin += text_compensation; data->xmin += text_compensation;
data->xmax -= text_compensation; /* Reduce the drawable area so that data->xmax -= text_compensation; /* Reduce the drawable area so that
* the node name is not lost * the node name is not lost
* TODO: Need a function to calculate * TODO: Need a function to calculate
* text_compensation depending on font size */ * text_compensation depending on font size */
data->x_rad_max = 0.9 * (data->xmax - data->xmin) / 2; data->x_rad_max = 0.9 * (data->xmax - data->xmin) / 2;
data->y_rad_max = 0.9 * (data->ymax - data->ymin) / 2; data->y_rad_max = 0.9 * (data->ymax - data->ymin) / 2;
data->x_inner_rad_max = data->x_rad_max / 2; data->x_inner_rad_max = data->x_rad_max / 2;
data->y_inner_rad_max = data->y_rad_max / 2; data->y_inner_rad_max = data->y_rad_max / 2;
skipping to change at line 1313 skipping to change at line 1316
* min and max, though with some tweaking to keep things away from the very * min and max, though with some tweaking to keep things away from the very
* edges of the range). * edges of the range).
*/ */
static gdouble scale_within(gdouble min, gdouble max, guint pos, guint num) static gdouble scale_within(gdouble min, gdouble max, guint pos, guint num)
{ {
return min + (((max - min) / (num + 1)) * (pos + 1)); return min + (((max - min) / (num + 1)) * (pos + 1));
} }
/* Called from update_diagram if the global need_reposition /* Called from update_diagram if the global need_reposition
* is set. It rearranges the nodes*/ * is set. It rearranges the nodes*/
/* TODO I think I should update all links as well, so as not having
* stale graphics if the diagram has been resized */
static gint reposition_canvas_nodes(node_id_t * node_id, static gint reposition_canvas_nodes(node_id_t * node_id,
canvas_node_t * canvas_node, canvas_node_t * canvas_node,
reposition_node_t *data) reposition_node_t *data)
{ {
struct node_ring *ring; struct node_ring *ring;
gdouble center_x, center_y, oddAngle; gdouble center_x, center_y, oddAngle;
gdouble x = 0, y = 0; gdouble x = 0, y = 0;
if (!canvas_node->shown) if (!canvas_node->shown)
{ {
gnome_canvas_item_hide (canvas_node->node_item); goo_canvas_item_hide(canvas_node->node_item);
gnome_canvas_item_hide (canvas_node->text_item); goo_canvas_item_hide(canvas_node->text_item);
return FALSE; return FALSE;
} }
ring = canvas_node->centered ? &data->center : &data->outer; ring = canvas_node->centered ? &data->center : &data->outer;
center_x = (data->xmax - data->xmin) / 2 + data->xmin; center_x = (data->xmax - data->xmin) / 2 + data->xmin;
center_y = (data->ymax - data->ymin) / 2 + data->ymin; center_y = (data->ymax - data->ymin) / 2 + data->ymin;
/* TODO I've done all the stationary changes in a hurry /* TODO I've done all the stationary changes in a hurry
* I should review it an tidy up all this stuff */ * I should review it an tidy up all this stuff */
skipping to change at line 1411 skipping to change at line 1412
{ {
/* For the inner ring, just move it proportionally closer the the center point. */ /* For the inner ring, just move it proportionally closer the the center point. */
x = center_x + ((x - center_x) * pref.inner_ring_scale); x = center_x + ((x - center_x) * pref.inner_ring_scale);
y = center_y + ((y - center_y) * pref.inner_ring_scale); y = center_y + ((y - center_y) * pref.inner_ring_scale);
} }
} }
} }
if (!appdata.stationary_layout || canvas_node->is_new) if (!appdata.stationary_layout || canvas_node->is_new)
{ {
gnome_canvas_item_set(GNOME_CANVAS_ITEM (canvas_node->group_item), g_object_set( G_OBJECT(canvas_node->group_item),
"x", x, "y", y, NULL); "x", x,
"y", y,
NULL);
canvas_node->is_new = FALSE; canvas_node->is_new = FALSE;
} }
if (need_font_refresh) if (need_font_refresh)
{ {
/* We update the text font */ /* update text font */
gnome_canvas_item_set (canvas_node->text_item, g_object_set( G_OBJECT(canvas_node->text_item),
"font", pref.fontname, "font", pref.fontname,
"fill_color", pref.text_color, "fill_color", pref.text_color,
NULL); NULL);
} }
if (pref.diagram_only) if (pref.diagram_only)
{ {
gnome_canvas_item_hide (canvas_node->text_item); goo_canvas_item_hide(canvas_node->text_item);
} }
else else
{ {
gnome_canvas_item_show (canvas_node->text_item); goo_canvas_item_show(canvas_node->text_item);
gnome_canvas_item_request_update (canvas_node->text_item); goo_canvas_item_request_update(canvas_node->text_item);
} }
gnome_canvas_item_show (canvas_node->node_item); goo_canvas_item_show(canvas_node->node_item);
gnome_canvas_item_request_update (canvas_node->node_item); goo_canvas_item_request_update(canvas_node->node_item);
ring->node_i--; ring->node_i--;
if (ring->node_i) if (ring->node_i)
ring->angle += 2 * M_PI / ring->n_nodes; ring->angle += 2 * M_PI / ring->n_nodes;
else else
{ {
ring->angle = 0.0; ring->angle = 0.0;
ring->n_nodes = 0; ring->n_nodes = 0;
} }
return FALSE; return FALSE;
} }
/* Goes through all known links and checks whether there already exists /* Goes through all known links and checks whether there already exists
* a corresponding canvas_link. If not, create it.*/ * a corresponding canvas_link. If not, create it.*/
static gint static gint check_new_link(link_id_t * link_id, link_t * link, GooCanvas *canvas
check_new_link (link_id_t * link_id, link_t * link, GtkWidget * canvas) )
{ {
canvas_link_t *new_canvas_link; canvas_link_t *new_canvas_link;
GnomeCanvasGroup *group; gulong sig_id;
GnomeCanvasPoints *points; GooCanvasItem *rootgroup;
guint i = 0;
if (!g_tree_lookup (canvas_links, link_id)) if (!g_tree_lookup (canvas_links, link_id))
{ {
group = gnome_canvas_root (GNOME_CANVAS (canvas)); rootgroup = goo_canvas_get_root_item(canvas);
new_canvas_link = g_malloc (sizeof (canvas_link_t)); new_canvas_link = g_malloc (sizeof (canvas_link_t));
g_assert(new_canvas_link); g_assert(new_canvas_link);
new_canvas_link->canvas_link_id = *link_id; new_canvas_link->canvas_link_id = *link_id;
/* We set the lines position using groups positions */ /* set the lines position using groups positions */
points = gnome_canvas_points_new (3); new_canvas_link->src_item =
goo_canvas_polyline_new(rootgroup, TRUE, 2,
for (; i <= 5; i++) 0,0,
points->coords[i] = 0.0; 1,1,
"fill-color", "tan",
new_canvas_link->src_item NULL);
= gnome_canvas_item_new (group, g_object_ref(G_OBJECT (new_canvas_link->src_item));
gnome_canvas_polygon_get_type (),
"points", points, "fill_color", "tan", NULL); new_canvas_link->dst_item =
addref_canvas_obj(G_OBJECT (new_canvas_link->src_item)); goo_canvas_polyline_new(rootgroup, TRUE, 2,
0,0,
new_canvas_link->dst_item 1,1,
= gnome_canvas_item_new (group, "fill-color", "tan",
gnome_canvas_polygon_get_type (), NULL);
"points", points, "fill_color", "tan", NULL); g_object_ref(G_OBJECT (new_canvas_link->dst_item));
addref_canvas_obj(G_OBJECT (new_canvas_link->dst_item));
g_tree_insert (canvas_links, g_tree_insert (canvas_links,
&new_canvas_link->canvas_link_id, new_canvas_link); &new_canvas_link->canvas_link_id, new_canvas_link);
gnome_canvas_item_lower_to_bottom (new_canvas_link->src_item); goo_canvas_item_lower(new_canvas_link->src_item, NULL);
gnome_canvas_item_lower_to_bottom (new_canvas_link->dst_item); goo_canvas_item_lower(new_canvas_link->dst_item, NULL);
gnome_canvas_points_unref (points);
g_signal_connect (G_OBJECT (new_canvas_link->src_item), "event",
G_CALLBACK(link_item_event), new_canvas_link);
g_signal_connect (G_OBJECT (new_canvas_link->dst_item), "event",
G_CALLBACK(link_item_event), new_canvas_link);
sig_id = g_signal_connect(G_OBJECT(new_canvas_link->src_item),
"button-release-event",
G_CALLBACK(link_item_event),
new_canvas_link);
g_assert(sig_id > 0);
sig_id = g_signal_connect(G_OBJECT(new_canvas_link->dst_item),
"button-release-event",
G_CALLBACK(link_item_event),
new_canvas_link);
sig_id = g_signal_connect(G_OBJECT(new_canvas_link->src_item),
"enter-notify-event",
G_CALLBACK(link_item_event),
new_canvas_link);
g_assert(sig_id > 0);
sig_id = g_signal_connect(G_OBJECT(new_canvas_link->src_item),
"leave-notify-event",
G_CALLBACK(link_item_event),
new_canvas_link);
g_assert(sig_id > 0);
} }
return FALSE; return FALSE;
} /* check_new_link */ } /* check_new_link */
/* - calls update_links, so that the related link updates its average /* - calls update_links, so that the related link updates its average
* traffic and main protocol, and old links are deleted * traffic and main protocol, and old links are deleted
* - caculates link size and color fading */ * - caculates link size and color fading */
static gint static gint canvas_link_update(link_id_t * link_id, canvas_link_t * canvas_link,
canvas_link_update(link_id_t * link_id, canvas_link_t * canvas_link, GList **delete_list)
GList **delete_list)
{ {
const link_t *link; const link_t *link;
const canvas_node_t *canvas_dst; const canvas_node_t *canvas_dst;
const canvas_node_t *canvas_src; const canvas_node_t *canvas_src;
guint32 scaledColor; GdkRGBA scaledColor;
double xs, ys, xd, yd, scale; double xs, ys, xd, yd, scale;
/* We used to run update_link here, but that was a major performance penalty, /* We used to run update_link here, but that was a major performance penalty,
* and now it is done in update_diagram */ * and now it is done in update_diagram */
link = links_catalog_find(link_id); link = links_catalog_find(link_id);
if (!link) if (!link)
{ {
*delete_list = g_list_prepend( *delete_list, link_id); *delete_list = g_list_prepend( *delete_list, link_id);
g_my_debug ("Queueing canvas link to remove."); g_my_debug ("Queueing canvas link to remove.");
return FALSE; return FALSE;
} }
/* If either source or destination has disappeared, we hide the link /* If either source or destination has disappeared, we hide the link
* until it can be show again */ * until it can be show again */
/* We get coords for the destination node */ /* We get coords for the destination node */
canvas_dst = g_tree_lookup (canvas_nodes, &link_id->dst); canvas_dst = g_tree_lookup (canvas_nodes, &link_id->dst);
if (!canvas_dst || !canvas_dst->shown) if (!canvas_dst || !canvas_dst->shown)
{ {
gnome_canvas_item_hide (canvas_link->src_item); goo_canvas_item_hide(canvas_link->src_item);
gnome_canvas_item_hide (canvas_link->dst_item); goo_canvas_item_hide(canvas_link->dst_item);
return FALSE; return FALSE;
} }
/* We get coords from source node */ /* We get coords from source node */
canvas_src = g_tree_lookup (canvas_nodes, &link_id->src); canvas_src = g_tree_lookup (canvas_nodes, &link_id->src);
if (!canvas_src || !canvas_src->shown) if (!canvas_src || !canvas_src->shown)
{ {
gnome_canvas_item_hide (canvas_link->src_item); goo_canvas_item_hide(canvas_link->src_item);
gnome_canvas_item_hide (canvas_link->dst_item); goo_canvas_item_hide(canvas_link->dst_item);
return FALSE; return FALSE;
} }
/* What if there never is a protocol? /* What if there never is a protocol?
* I have to initialize canvas_link->color to a known value */ * I have to initialize canvas_link->color to a known value */
if (link->main_prot[pref.stack_level]) if (link->main_prot[pref.stack_level])
{ {
double diffms; double diffms;
canvas_link->color = protohash_color(link->main_prot[pref.stack_level]); canvas_link->color = *protohash_color(link->main_prot[pref.stack_level]);
/* scale color down to 10% at link timeout */ /* scale color down to 10% at link timeout */
diffms = subtract_times_ms(&appdata.now, &link->link_stats.stats.last_time ); diffms = subtract_times_ms(&appdata.now, &link->link_stats.stats.last_time );
scale = pow(0.10, diffms / pref.gui_link_timeout_time); scale = pow(0.10, diffms / pref.gui_link_timeout_time);
scaledColor = scaledColor.red = scale * canvas_link->color.red;
(((guint32) (scale * canvas_link->color.red) & 0xFF00) << 16) | scaledColor.green = scale * canvas_link->color.green;
(((guint32) (scale * canvas_link->color.green) & 0xFF00) << 8) | scaledColor.blue = scale * canvas_link->color.blue;
((guint32) (scale * canvas_link->color.blue) & 0xFF00) | 0xFF; scaledColor.alpha = 1;
} }
else else
{ {
guint32 black = 0x000000ff; // black
scaledColor = black; scaledColor.red = 0;
scaledColor.green = 0;
scaledColor.blue = 0;
scaledColor.alpha = 1;
} }
/* retrieve coordinates of node centers */ /* retrieve coordinates of node centers */
g_object_get (G_OBJECT (canvas_src->group_item), "x", &xs, "y", &ys, NULL); g_object_get(G_OBJECT(canvas_src->group_item), "x", &xs, "y", &ys, NULL);
g_object_get (G_OBJECT (canvas_dst->group_item), "x", &xd, "y", &yd, NULL); g_object_get(G_OBJECT(canvas_dst->group_item), "x", &xd, "y", &yd, NULL);
/* first draw triangle for src->dst */ /* first draw triangle for src->dst */
draw_oneside_link(xs, ys, xd, yd, &(link->link_stats.stats_out), scaledColor, draw_oneside_link(xs, ys, xd, yd, &(link->link_stats.stats_out), &scaledColor,
canvas_link->src_item); canvas_link->src_item);
/* then draw triangle for dst->src */ /* then draw triangle for dst->src */
draw_oneside_link(xd, yd, xs, ys, &(link->link_stats.stats_in), scaledColor, draw_oneside_link(xd, yd, xs, ys, &(link->link_stats.stats_in), &scaledColor,
canvas_link->dst_item); canvas_link->dst_item);
return FALSE; return FALSE;
} /* update_canvas_links */ } /* update_canvas_links */
/* given the src and dst node centers, plus a size, draws a triangle in the /* given the src and dst node centers, plus a size, draws a triangle in the
* specified color on the provided canvas item*/ * specified color on the provided canvas item*/
static void draw_oneside_link(double xs, double ys, double xd, double yd, static void draw_oneside_link(double xs, double ys, double xd, double yd,
const basic_stats_t *link_stats, const basic_stats_t *link_stats,
guint32 scaledColor, GnomeCanvasItem *item) const GdkRGBA *scaledColor, GooCanvasItem *item)
{ {
GnomeCanvasPoints *points; GooCanvasPoints *points;
gdouble versorx, versory, modulus, link_size; gdouble versorx, versory, modulus, link_size;
link_size = get_link_size(link_stats) / 2; link_size = get_link_size(link_stats) / 2;
/* limit the maximum size to avoid overload */ /* limit the maximum size to avoid overload */
if (link_size > MAX_LINK_SIZE) if (link_size > MAX_LINK_SIZE)
link_size = MAX_LINK_SIZE; link_size = MAX_LINK_SIZE;
versorx = -(yd - ys); versorx = -(yd - ys);
versory = xd - xs; versory = xd - xs;
modulus = sqrt (pow (versorx, 2) + pow (versory, 2)); modulus = sqrt (pow (versorx, 2) + pow (versory, 2));
if (modulus == 0) if (modulus == 0)
{ {
link_size = 0; link_size = 0;
modulus = 1; modulus = 1;
} }
points = gnome_canvas_points_new (3); points = goo_canvas_points_new(3);
points->coords[0] = xd; points->coords[0] = xd;
points->coords[1] = yd; points->coords[1] = yd;
points->coords[2] = xs + versorx * link_size / modulus; points->coords[2] = xs + versorx * link_size / modulus;
points->coords[3] = ys + versory * link_size / modulus; points->coords[3] = ys + versory * link_size / modulus;
points->coords[4] = xs - versorx * link_size / modulus; points->coords[4] = xs - versorx * link_size / modulus;
points->coords[5] = ys - versory * link_size / modulus; points->coords[5] = ys - versory * link_size / modulus;
gnome_canvas_item_set (item,
"points", points,
"fill_color_rgba", scaledColor, NULL);
/* If we got this far, the link can be shown. Make sure it is */ /* If we got this far, the link can be shown. Make sure it is */
gnome_canvas_item_show (item); g_object_set(G_OBJECT(item),
gnome_canvas_points_unref (points); "points", points,
"fill-color-gdk-rgba", scaledColor,
"stroke-color-gdk-rgba", scaledColor,
"visibility", GOO_CANVAS_ITEM_VISIBLE,
NULL);
goo_canvas_points_unref(points);
} }
/* Returs the radius in pixels given average traffic and size mode */ /* Returs the radius in pixels given average traffic and size mode */
static gdouble static gdouble get_node_size (gdouble average)
get_node_size (gdouble average)
{ {
gdouble result = 0.0; gdouble result = 0.0;
switch (pref.size_mode) switch (pref.size_mode)
{ {
case LINEAR: case LINEAR:
result = average + 1; result = average + 1;
break; break;
case LOG: case LOG:
result = log (average + 1); result = log (average + 1);
break; break;
skipping to change at line 1694 skipping to change at line 1710
result = log(data + 1); result = log(data + 1);
break; break;
case SQRT: case SQRT:
result = sqrt(data + 1); result = sqrt(data + 1);
break; break;
} }
return 1.0 + pref.node_radius_multiplier * pref.link_node_ratio * result; return 1.0 + pref.node_radius_multiplier * pref.link_node_ratio * result;
} /* get_link_size */ } /* get_link_size */
/* Called for every event a link receives. Right now it's used to /* Called for every event a link receives. Right now it's used to
* set a message in the statusbar */ * set a message in the statusbar and launch the popup */
static gint static gboolean link_item_event(GooCanvasItem *item,
link_item_event (GnomeCanvasItem * item, GdkEvent * event, GooCanvasItem *target_item,
canvas_link_t * canvas_link) GdkEventButton *event,
canvas_link_t * canvas_link)
{ {
gchar *str; gchar *str;
const link_t *link=NULL; const link_t *link=NULL;
switch (event->type) switch (event->type)
{ {
case GDK_BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
case GDK_2BUTTON_PRESS: case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
if (canvas_link) if (canvas_link)
link_info_window_create( &canvas_link->canvas_link_id ); link_info_window_create(&canvas_link->canvas_link_id);
break; break;
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
if (canvas_link) if (canvas_link)
link = links_catalog_find(&canvas_link->canvas_link_id); link = links_catalog_find(&canvas_link->canvas_link_id);
if (link && link->main_prot[pref.stack_level]) if (link && link->main_prot[pref.stack_level])
str = g_strdup_printf (_("Link main protocol: %s"), str = g_strdup_printf(_("Link main protocol: %s"),
link->main_prot[pref.stack_level]); link->main_prot[pref.stack_level]);
else else
str = g_strdup_printf (_("Link main protocol unknown")); str = g_strdup_printf(_("Link main protocol: unknown"));
gtk_statusbar_push(appdata.statusbar, 1, str); gtk_statusbar_push(appdata.statusbar, 1, str);
g_free (str); g_free(str);
break; break;
case GDK_LEAVE_NOTIFY: case GDK_LEAVE_NOTIFY:
gtk_statusbar_pop(appdata.statusbar, 1); gtk_statusbar_pop(appdata.statusbar, 1);
break; break;
default: default:
break; break;
} }
return FALSE; return FALSE;
} /* link_item_event */ } /* link_item_event */
/* Called for every event a node receives. Right now it's used to /* Called for every event a node receives. Right now it's used to
* set a message in the statusbar and launch the popup timeout */ * launch the popup */
static gint static gint node_item_event(GooCanvasItem *item,
node_item_event (GnomeCanvasItem * item, GdkEvent * event, GooCanvasItem *target_item,
canvas_node_t * canvas_node) GdkEventButton *event,
canvas_node_t * canvas_node)
{ {
gdouble item_x, item_y; // gdouble item_x, item_y;
const node_t *node = NULL; const node_t *node = NULL;
/* This is not used yet, but it will be. */ /* This is not used yet, but it will be. */
item_x = event->button.x; /* item_x = event->button.x;
item_y = event->button.y; item_y = event->button.y;
gnome_canvas_item_w2i (item->parent, &item_x, &item_y); gnome_canvas_item_w2i (item->parent, &item_x, &item_y);
*/
switch (event->type) switch (event->type)
{ {
case GDK_2BUTTON_PRESS: case GDK_BUTTON_PRESS:
if (canvas_node) case GDK_BUTTON_RELEASE:
node = nodes_catalog_find(&canvas_node->canvas_node_id); case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
if (canvas_node)
node = nodes_catalog_find(&canvas_node->canvas_node_id);
if (node) if (node)
{ {
node_protocols_window_create( &canvas_node->canvas_node_id ); node_protocols_window_create(&canvas_node->canvas_node_id);
g_my_info ("Nodes: %d (shown %u)", nodes_catalog_size(), g_my_info ("Nodes: %d (shown %u)", nodes_catalog_size(),
displayed_nodes); displayed_nodes);
if (DEBUG_ENABLED) if (DEBUG_ENABLED)
{ {
gchar *msg = node_dump(node); gchar *msg = node_dump(node);
g_my_debug("%s", msg); g_my_debug("%s", msg);
g_free(msg); g_free(msg);
} }
} }
break; break;
default: default:
break; break;
} }
return FALSE; return FALSE;
} /* node_item_event */ } /* node_item_event */
/* Explain pcap stats in status bar when moused over */ /* Explain pcap stats in status bar when moused over */
static gint pcap_stats_text_item_event(GnomeCanvasItem *item, GdkEvent *event, static gint pcap_stats_text_item_event(GooCanvasItem *item, GdkEvent *event,
void *unused) void *unused)
{ {
switch (event->type) switch (event->type)
{ {
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
gtk_statusbar_push(appdata.statusbar, 1, _("'recv': packets received; " gtk_statusbar_push(appdata.statusbar, 1, _("'recv': packets received; "
"'drop': packets dropped by OS buffering; " "'drop': packets dropped by OS buffering; "
"'ifdrop': packets dropped by i nterface or driver.")); "'ifdrop': packets dropped by i nterface or driver."));
break; break;
skipping to change at line 1797 skipping to change at line 1821
default: default:
break; break;
} }
return FALSE; return FALSE;
} }
/* Pushes a string into the statusbar stack */ /* Pushes a string into the statusbar stack */
void void
set_statusbar_msg (gchar * str) set_statusbar_msg(gchar * str)
{ {
static gchar *status_string = NULL; static gchar *status_string = NULL;
if (status_string) if (status_string)
g_free (status_string); g_free (status_string);
status_string = g_strdup (str); status_string = g_strdup (str);
gtk_statusbar_pop(appdata.statusbar, 0); gtk_statusbar_pop(appdata.statusbar, 0);
gtk_statusbar_push(appdata.statusbar, 0, status_string); gtk_statusbar_push(appdata.statusbar, 0, status_string);
skipping to change at line 1826 skipping to change at line 1850
} }
static gint canvas_link_compare(const link_id_t *a, const link_id_t *b, static gint canvas_link_compare(const link_id_t *a, const link_id_t *b,
gpointer dummy) gpointer dummy)
{ {
g_assert (a != NULL); g_assert (a != NULL);
g_assert (b != NULL); g_assert (b != NULL);
return link_id_compare(a, b); return link_id_compare(a, b);
} }
static void static void canvas_link_delete(canvas_link_t *canvas_link)
canvas_link_delete(canvas_link_t *canvas_link)
{ {
/* Right now I'm not very sure in which cases there could be a canvas_link bu t not a link_item, but /* Right now I'm not very sure in which cases there could be a canvas_link bu t not a link_item, but
* I had a not in update_canvas_nodes that if the test is not done it can lead to corruption */ * I had a not in update_canvas_nodes that if the test is not done it can lead to corruption */
if (canvas_link->src_item) if (canvas_link->src_item)
{ {
gtk_object_destroy (GTK_OBJECT (canvas_link->src_item)); goo_canvas_item_remove(canvas_link->src_item);
g_object_unref (G_OBJECT (canvas_link->src_item));
canvas_link->src_item = NULL; canvas_link->src_item = NULL;
} }
if (canvas_link->dst_item) if (canvas_link->dst_item)
{ {
gtk_object_destroy (GTK_OBJECT (canvas_link->dst_item)); goo_canvas_item_remove(canvas_link->dst_item);
g_object_unref (G_OBJECT (canvas_link->dst_item));
canvas_link->dst_item = NULL; canvas_link->dst_item = NULL;
} }
g_free (canvas_link); g_free (canvas_link);
} }
void timeout_changed(void) /* diagram timeout was changed. Remove old timer and register new */
void diagram_timeout_changed(void)
{
if (diagram_timeout)
g_source_remove(diagram_timeout);
diagram_timeout = g_timeout_add(pref.refresh_period,
update_diagram_ca
llback,
NULL);
}
void resize_diagram(const GtkAllocation *allocation)
{
goo_canvas_set_bounds(gcanvas_,
-allocation->width / 2,
-allocation->height / 2,
allocation->width / 2,
allocation->height / 2);
ask_reposition(FALSE);
redraw_canvas_background(gcanvas_);
update_diagram(gcanvas_);
}
gboolean update_diagram_callback(gpointer data)
{ {
/* When removing the source (which could either be an idle or a timeout update_diagram(gcanvas_);
* function, I'm also forcing the callback for the corresponding return TRUE;
* destroying function, which in turn will install a timeout or idle
* function using the new refresh_period. It might take a while for it
* to settle down, but I think it works now */
g_source_remove (diagram_timeout);
} }
 End of changes. 179 change blocks. 
473 lines changed or deleted 512 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)